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.
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>
28 kripto_mac_desc
*desc
;
37 kripto_hash_desc
*hash
,
40 const unsigned int key_len
45 if(key_len
> kripto_hash_blocksize(hash
))
53 kripto_hash_blocksize(hash
))
56 i
= kripto_hash_blocksize(hash
);
60 memcpy(s
->key
, key
, key_len
);
64 memset(s
->key
, 0, kripto_hash_blocksize(hash
) - i
);
66 for(i
= 0; i
< kripto_hash_blocksize(hash
); i
++)
69 kripto_hash_input(s
->hash
, s
->key
, i
);
74 static void hmac_destroy(kripto_mac
*s
)
76 kripto_hash_destroy(s
->hash
);
78 kripto_memwipe(s
, s
->size
);
82 static kripto_mac
*hmac_create
87 const unsigned int key_len
,
88 const unsigned int out_len
93 s
= malloc(sizeof(kripto_mac
) + kripto_hash_blocksize(hash
));
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
);
107 if(hmac_init(s
, hash
, r
, key
, key_len
))
116 static kripto_mac
*hmac_recreate
120 const unsigned int r
,
122 const unsigned int key_len
,
123 const unsigned int out_len
126 if(sizeof(kripto_mac
) + kripto_hash_blocksize(hash
) > s
->size
)
129 s
= hmac_create(hash
, r
, key
, key_len
, out_len
);
133 if(hash
== kripto_hash_get_desc(s
->hash
))
134 s
->hash
= kripto_hash_recreate(s
->hash
, out_len
, r
);
137 kripto_hash_destroy(s
->hash
);
138 s
->hash
= kripto_hash_create(hash
, out_len
, r
);
146 if(hmac_init(s
, hash
, r
, key
, key_len
))
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
)
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
=
188 kripto_mac_desc
*const kripto_mac_hmac
= &hmac
;