missing const
[rofl0r-kripto.git] / lib / mac / hmac.c
blobec56c3ef6524baa2285c033f4660a410fd01a25b
1 /*
2 * Copyright (C) 2013 Gregor Pintar <grpintar@gmail.com>
4 * Permission is granted to deal in this work without any restriction,
5 * including unlimited rights to use, publicly perform, publish,
6 * reproduce, relicence, modify, merge, and/or distribute in any form,
7 * for any purpose, with or without fee, and by any means.
9 * This work is provided "AS IS" and WITHOUT WARRANTY of any kind,
10 * to the utmost extent permitted by applicable law. In no event
11 * shall a licensor, author or contributor be held liable for any
12 * issues arising in any way out of dealing in the work.
15 #include <string.h>
16 #include <stdint.h>
17 #include <stdlib.h>
19 #include <kripto/memwipe.h>
20 #include <kripto/mac.h>
21 #include <kripto/mac_desc.h>
22 #include <kripto/hash.h>
24 #include <kripto/mac/hmac.h>
26 struct kripto_mac
28 kripto_mac_desc *desc;
29 kripto_hash *hash;
30 size_t size;
31 uint8_t *key;
34 static int hmac_init
36 kripto_mac *s,
37 kripto_hash_desc *hash,
38 const unsigned int r,
39 const void *key,
40 const unsigned int key_len
43 unsigned int i;
45 if(key_len > kripto_hash_blocksize(hash))
47 if(kripto_hash_all(
48 hash,
50 key,
51 key_len,
52 s->key,
53 kripto_hash_blocksize(hash))
54 ) return -1;
56 i = kripto_hash_blocksize(hash);
58 else
60 memcpy(s->key, key, key_len);
61 i = key_len;
64 memset(s->key, 0, kripto_hash_blocksize(hash) - i);
66 for(i = 0; i < kripto_hash_blocksize(hash); i++)
67 s->key[i] ^= 0x36;
69 kripto_hash_input(s->hash, s->key, i);
71 return 0;
74 static void hmac_destroy(kripto_mac *s)
76 kripto_hash_destroy(s->hash);
78 kripto_memwipe(s, s->size);
79 free(s);
82 static kripto_mac *hmac_create
84 const void *hash,
85 const unsigned int r,
86 const void *key,
87 const unsigned int key_len,
88 const unsigned int out_len
91 kripto_mac *s;
93 s = malloc(sizeof(kripto_mac) + kripto_hash_blocksize(hash));
94 if(!s) return 0;
96 s->key = (uint8_t *)s + sizeof(kripto_mac);
98 s->desc = kripto_mac_hmac;
99 s->size = sizeof(kripto_mac) + kripto_hash_blocksize(hash);
100 s->hash = kripto_hash_create(hash, out_len, r);
101 if(!s->hash)
103 free(s);
104 return 0;
107 if(hmac_init(s, hash, r, key, key_len))
109 hmac_destroy(s);
110 return 0;
113 return s;
116 static kripto_mac *hmac_recreate
118 kripto_mac *s,
119 const void *hash,
120 const unsigned int r,
121 const void *key,
122 const unsigned int key_len,
123 const unsigned int out_len
126 if(sizeof(kripto_mac) + kripto_hash_blocksize(hash) > s->size)
128 hmac_destroy(s);
129 s = hmac_create(hash, r, key, key_len, out_len);
131 else
133 if(hash == kripto_hash_get_desc(s->hash))
134 s->hash = kripto_hash_recreate(s->hash, out_len, r);
135 else
137 kripto_hash_destroy(s->hash);
138 s->hash = kripto_hash_create(hash, out_len, r);
139 if(!s->hash)
141 hmac_destroy(s);
142 return 0;
146 if(hmac_init(s, hash, r, key, key_len))
148 hmac_destroy(s);
149 return 0;
153 return s;
156 static void hmac_update(kripto_mac *s, const void *in, const size_t len)
158 kripto_hash_input(s->hash, in, len);
161 static void hmac_finish(kripto_mac *s, void *out, const size_t len)
163 unsigned int i;
165 for(i = 0; i < kripto_hash_blocksize(kripto_hash_get_desc(s->hash)); i++)
166 s->key[i] ^= 0x6A; /* 0x5C ^ 0x36 */
168 kripto_hash_input(s->hash, s->key, i);
169 kripto_hash_finish(s->hash);
170 kripto_hash_output(s->hash, out, len);
173 static unsigned int hmac_max_output(const void *hash)
175 return kripto_hash_max_output(kripto_hash_get_desc(hash));
178 static const struct kripto_mac_desc hmac =
180 &hmac_create,
181 &hmac_recreate,
182 &hmac_update,
183 &hmac_finish,
184 &hmac_destroy,
185 &hmac_max_output
188 kripto_mac_desc *const kripto_mac_hmac = &hmac;