updated makefiles
[gnutls.git] / lib / nettle / mac.c
blobacaacf4a8471274a05407c0b995dabd152762fe7
1 /*
2 * Copyright (C) 2008-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GNUTLS.
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 3 of
11 * the License, or (at your option) any later version.
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.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 /* This file provides the backend hash/mac API for nettle.
26 #include <gnutls_int.h>
27 #include <gnutls_hash_int.h>
28 #include <gnutls_errors.h>
29 #include <nettle/md5.h>
30 #include <nettle/md2.h>
31 #include <nettle/sha.h>
32 #include <nettle/hmac.h>
34 typedef void (*update_func) (void *, unsigned, const uint8_t *);
35 typedef void (*digest_func) (void *, unsigned, uint8_t *);
36 typedef void (*set_key_func) (void *, unsigned, const uint8_t *);
38 static int wrap_nettle_hash_init (gnutls_digest_algorithm_t algo, void **_ctx);
40 struct nettle_hash_ctx
42 union
44 struct md5_ctx md5;
45 struct md2_ctx md2;
46 struct sha224_ctx sha224;
47 struct sha256_ctx sha256;
48 struct sha384_ctx sha384;
49 struct sha512_ctx sha512;
50 struct sha1_ctx sha1;
51 } ctx;
52 void *ctx_ptr;
53 gnutls_digest_algorithm_t algo;
54 size_t length;
55 update_func update;
56 digest_func digest;
59 struct nettle_hmac_ctx
61 union
63 struct hmac_md5_ctx md5;
64 struct hmac_sha224_ctx sha224;
65 struct hmac_sha256_ctx sha256;
66 struct hmac_sha384_ctx sha384;
67 struct hmac_sha512_ctx sha512;
68 struct hmac_sha1_ctx sha1;
69 } ctx;
71 /* this is the context just after
72 * the set_key. Used in reset().
74 union
76 struct hmac_md5_ctx md5;
77 struct hmac_sha224_ctx sha224;
78 struct hmac_sha256_ctx sha256;
79 struct hmac_sha384_ctx sha384;
80 struct hmac_sha512_ctx sha512;
81 struct hmac_sha1_ctx sha1;
82 } init_ctx;
83 void *ctx_ptr;
84 gnutls_mac_algorithm_t algo;
85 size_t length;
86 update_func update;
87 digest_func digest;
88 set_key_func setkey;
91 static int _hmac_ctx_init(gnutls_mac_algorithm_t algo, struct nettle_hmac_ctx *ctx)
93 switch (algo)
95 case GNUTLS_MAC_MD5:
96 ctx->update = (update_func) hmac_md5_update;
97 ctx->digest = (digest_func) hmac_md5_digest;
98 ctx->setkey = (set_key_func) hmac_md5_set_key;
99 ctx->ctx_ptr = &ctx->ctx.md5;
100 ctx->length = MD5_DIGEST_SIZE;
101 break;
102 case GNUTLS_MAC_SHA1:
103 ctx->update = (update_func) hmac_sha1_update;
104 ctx->digest = (digest_func) hmac_sha1_digest;
105 ctx->setkey = (set_key_func) hmac_sha1_set_key;
106 ctx->ctx_ptr = &ctx->ctx.sha1;
107 ctx->length = SHA1_DIGEST_SIZE;
108 break;
109 case GNUTLS_MAC_SHA224:
110 ctx->update = (update_func) hmac_sha224_update;
111 ctx->digest = (digest_func) hmac_sha224_digest;
112 ctx->setkey = (set_key_func) hmac_sha224_set_key;
113 ctx->ctx_ptr = &ctx->ctx.sha224;
114 ctx->length = SHA224_DIGEST_SIZE;
115 break;
116 case GNUTLS_MAC_SHA256:
117 ctx->update = (update_func) hmac_sha256_update;
118 ctx->digest = (digest_func) hmac_sha256_digest;
119 ctx->setkey = (set_key_func) hmac_sha256_set_key;
120 ctx->ctx_ptr = &ctx->ctx.sha256;
121 ctx->length = SHA256_DIGEST_SIZE;
122 break;
123 case GNUTLS_MAC_SHA384:
124 ctx->update = (update_func) hmac_sha384_update;
125 ctx->digest = (digest_func) hmac_sha384_digest;
126 ctx->setkey = (set_key_func) hmac_sha384_set_key;
127 ctx->ctx_ptr = &ctx->ctx.sha384;
128 ctx->length = SHA384_DIGEST_SIZE;
129 break;
130 case GNUTLS_MAC_SHA512:
131 ctx->update = (update_func) hmac_sha512_update;
132 ctx->digest = (digest_func) hmac_sha512_digest;
133 ctx->setkey = (set_key_func) hmac_sha512_set_key;
134 ctx->ctx_ptr = &ctx->ctx.sha512;
135 ctx->length = SHA512_DIGEST_SIZE;
136 break;
137 default:
138 gnutls_assert ();
139 return GNUTLS_E_INVALID_REQUEST;
142 return 0;
145 static int wrap_nettle_hmac_fast(gnutls_mac_algorithm_t algo,
146 const void *key, size_t key_size, const void* text, size_t text_size,
147 void* digest)
149 struct nettle_hmac_ctx ctx;
150 int ret;
152 ret = _hmac_ctx_init(algo, &ctx);
153 if (ret < 0)
154 return gnutls_assert_val(ret);
156 ctx.setkey (&ctx, key_size, key);
157 ctx.update (&ctx, text_size, text);
158 ctx.digest (&ctx, ctx.length, digest);
160 return 0;
163 static int wrap_nettle_hmac_exists(gnutls_mac_algorithm_t algo)
165 switch (algo)
167 case GNUTLS_MAC_MD5:
168 case GNUTLS_MAC_SHA1:
169 case GNUTLS_MAC_SHA224:
170 case GNUTLS_MAC_SHA256:
171 case GNUTLS_MAC_SHA384:
172 case GNUTLS_MAC_SHA512:
173 return 1;
174 default:
175 return 0;
179 static int
180 wrap_nettle_hmac_init (gnutls_mac_algorithm_t algo, void **_ctx)
182 struct nettle_hmac_ctx *ctx;
183 int ret;
185 ctx = gnutls_calloc (1, sizeof (struct nettle_hmac_ctx));
186 if (ctx == NULL)
188 gnutls_assert ();
189 return GNUTLS_E_MEMORY_ERROR;
192 ctx->algo = algo;
194 ret = _hmac_ctx_init(algo, ctx);
195 if (ret < 0)
197 gnutls_free(ctx);
198 return gnutls_assert_val(ret);
201 *_ctx = ctx;
203 return 0;
206 static int
207 wrap_nettle_hmac_setkey (void *_ctx, const void *key, size_t keylen)
209 struct nettle_hmac_ctx *ctx = _ctx;
211 ctx->setkey (ctx->ctx_ptr, keylen, key);
213 memcpy(&ctx->init_ctx, &ctx->ctx, sizeof(ctx->ctx));
215 return GNUTLS_E_SUCCESS;
218 static void
219 wrap_nettle_hmac_reset (void *_ctx)
221 struct nettle_hmac_ctx *ctx = _ctx;
223 memcpy(&ctx->ctx, &ctx->init_ctx, sizeof(ctx->ctx));
226 static int
227 wrap_nettle_hmac_update (void *_ctx, const void *text, size_t textsize)
229 struct nettle_hmac_ctx *ctx = _ctx;
231 ctx->update (ctx->ctx_ptr, textsize, text);
233 return GNUTLS_E_SUCCESS;
236 static int
237 wrap_nettle_hmac_output (void *src_ctx, void *digest, size_t digestsize)
239 struct nettle_hmac_ctx *ctx;
240 ctx = src_ctx;
242 if (digestsize < ctx->length)
244 gnutls_assert ();
245 return GNUTLS_E_SHORT_MEMORY_BUFFER;
248 ctx->digest (ctx->ctx_ptr, digestsize, digest);
250 return 0;
253 static void
254 wrap_nettle_hmac_deinit (void *hd)
256 gnutls_free (hd);
259 /* Hash functions
261 static int
262 wrap_nettle_hash_update (void *_ctx, const void *text, size_t textsize)
264 struct nettle_hash_ctx *ctx = _ctx;
266 ctx->update (ctx->ctx_ptr, textsize, text);
268 return GNUTLS_E_SUCCESS;
271 static void
272 wrap_nettle_hash_deinit (void *hd)
274 gnutls_free (hd);
277 static int wrap_nettle_hash_exists(gnutls_digest_algorithm_t algo)
279 switch (algo)
281 case GNUTLS_DIG_MD5:
282 case GNUTLS_DIG_SHA1:
283 case GNUTLS_DIG_MD2:
284 case GNUTLS_DIG_SHA224:
285 case GNUTLS_DIG_SHA256:
286 case GNUTLS_DIG_SHA384:
287 case GNUTLS_DIG_SHA512:
288 return 1;
289 default:
290 return 0;
294 static int _ctx_init(gnutls_digest_algorithm_t algo, struct nettle_hash_ctx *ctx)
296 switch (algo)
298 case GNUTLS_DIG_MD5:
299 md5_init (&ctx->ctx.md5);
300 ctx->update = (update_func) md5_update;
301 ctx->digest = (digest_func) md5_digest;
302 ctx->ctx_ptr = &ctx->ctx.md5;
303 ctx->length = MD5_DIGEST_SIZE;
304 break;
305 case GNUTLS_DIG_SHA1:
306 sha1_init (&ctx->ctx.sha1);
307 ctx->update = (update_func) sha1_update;
308 ctx->digest = (digest_func) sha1_digest;
309 ctx->ctx_ptr = &ctx->ctx.sha1;
310 ctx->length = SHA1_DIGEST_SIZE;
311 break;
312 case GNUTLS_DIG_MD2:
313 md2_init (&ctx->ctx.md2);
314 ctx->update = (update_func) md2_update;
315 ctx->digest = (digest_func) md2_digest;
316 ctx->ctx_ptr = &ctx->ctx.md2;
317 ctx->length = MD2_DIGEST_SIZE;
318 break;
319 case GNUTLS_DIG_SHA224:
320 sha224_init (&ctx->ctx.sha224);
321 ctx->update = (update_func) sha224_update;
322 ctx->digest = (digest_func) sha224_digest;
323 ctx->ctx_ptr = &ctx->ctx.sha224;
324 ctx->length = SHA224_DIGEST_SIZE;
325 break;
326 case GNUTLS_DIG_SHA256:
327 sha256_init (&ctx->ctx.sha256);
328 ctx->update = (update_func) sha256_update;
329 ctx->digest = (digest_func) sha256_digest;
330 ctx->ctx_ptr = &ctx->ctx.sha256;
331 ctx->length = SHA256_DIGEST_SIZE;
332 break;
333 case GNUTLS_DIG_SHA384:
334 sha384_init (&ctx->ctx.sha384);
335 ctx->update = (update_func) sha384_update;
336 ctx->digest = (digest_func) sha384_digest;
337 ctx->ctx_ptr = &ctx->ctx.sha384;
338 ctx->length = SHA384_DIGEST_SIZE;
339 break;
340 case GNUTLS_DIG_SHA512:
341 sha512_init (&ctx->ctx.sha512);
342 ctx->update = (update_func) sha512_update;
343 ctx->digest = (digest_func) sha512_digest;
344 ctx->ctx_ptr = &ctx->ctx.sha512;
345 ctx->length = SHA512_DIGEST_SIZE;
346 break;
347 default:
348 gnutls_assert ();
349 return GNUTLS_E_INVALID_REQUEST;
352 return 0;
355 static int wrap_nettle_hash_fast(gnutls_digest_algorithm_t algo,
356 const void* text, size_t text_size,
357 void* digest)
359 struct nettle_hash_ctx ctx;
360 int ret;
362 ret = _ctx_init(algo, &ctx);
363 if (ret < 0)
364 return gnutls_assert_val(ret);
366 ctx.update (&ctx, text_size, text);
367 ctx.digest (&ctx, ctx.length, digest);
369 return 0;
372 static int
373 wrap_nettle_hash_init (gnutls_digest_algorithm_t algo, void **_ctx)
375 struct nettle_hash_ctx *ctx;
376 int ret;
378 ctx = gnutls_malloc (sizeof (struct nettle_hash_ctx));
379 if (ctx == NULL)
381 gnutls_assert ();
382 return GNUTLS_E_MEMORY_ERROR;
385 ctx->algo = algo;
387 if ((ret=_ctx_init( algo, ctx)) < 0)
389 gnutls_assert ();
390 gnutls_free(ctx);
391 return ret;
394 *_ctx = ctx;
396 return 0;
399 static int
400 wrap_nettle_hash_output (void *src_ctx, void *digest, size_t digestsize)
402 struct nettle_hash_ctx *ctx;
403 ctx = src_ctx;
405 if (digestsize < ctx->length)
407 gnutls_assert ();
408 return GNUTLS_E_SHORT_MEMORY_BUFFER;
411 ctx->digest (ctx->ctx_ptr, digestsize, digest);
413 return 0;
416 static void
417 wrap_nettle_hash_reset (void *src_ctx)
419 struct nettle_hash_ctx *ctx;
420 ctx = src_ctx;
422 _ctx_init(ctx->algo, ctx->ctx_ptr);
426 gnutls_crypto_mac_st _gnutls_mac_ops = {
427 .init = wrap_nettle_hmac_init,
428 .setkey = wrap_nettle_hmac_setkey,
429 .hash = wrap_nettle_hmac_update,
430 .reset = wrap_nettle_hmac_reset,
431 .output = wrap_nettle_hmac_output,
432 .deinit = wrap_nettle_hmac_deinit,
433 .fast = wrap_nettle_hmac_fast,
434 .exists = wrap_nettle_hmac_exists,
437 gnutls_crypto_digest_st _gnutls_digest_ops = {
438 .init = wrap_nettle_hash_init,
439 .hash = wrap_nettle_hash_update,
440 .reset = wrap_nettle_hash_reset,
441 .output = wrap_nettle_hash_output,
442 .deinit = wrap_nettle_hash_deinit,
443 .fast = wrap_nettle_hash_fast,
444 .exists = wrap_nettle_hash_exists,