aboutsummaryrefslogtreecommitdiffstats
path: root/Source/charon/transforms/hmac.c
diff options
context:
space:
mode:
Diffstat (limited to 'Source/charon/transforms/hmac.c')
-rw-r--r--Source/charon/transforms/hmac.c61
1 files changed, 45 insertions, 16 deletions
diff --git a/Source/charon/transforms/hmac.c b/Source/charon/transforms/hmac.c
index 1f078ebf0..809c7f8bb 100644
--- a/Source/charon/transforms/hmac.c
+++ b/Source/charon/transforms/hmac.c
@@ -68,20 +68,37 @@ struct private_hmac_s {
*/
static status_t get_mac(private_hmac_t *this, chunk_t data, u_int8_t *out)
{
- /* H(K XOR opad, H(K XOR ipad, text)) */
+ /* H(K XOR opad, H(K XOR ipad, text))
+ *
+ * if out is NULL, we append text to the inner hash.
+ * else, we complete the inner and do the outer.
+ *
+ */
+
u_int8_t buffer[this->h->get_block_size(this->h)];
chunk_t inner;
- inner.ptr = buffer;
- inner.len = this->h->get_block_size(this->h);
-
- /* inner */
- this->h->get_hash(this->h, this->ipaded_key, NULL);
- this->h->get_hash(this->h, data, buffer);
-
- /* outer */
- this->h->get_hash(this->h, this->opaded_key, NULL);
- this->h->get_hash(this->h, inner, out);
+ if (out == NULL)
+ {
+ /* append data to inner */
+ this->h->get_hash(this->h, data, NULL);
+ }
+ else
+ {
+ /* append and do outer hash */
+ inner.ptr = buffer;
+ inner.len = this->h->get_block_size(this->h);
+
+ /* complete inner */
+ this->h->get_hash(this->h, data, buffer);
+
+ /* do outer */
+ this->h->get_hash(this->h, this->opaded_key, NULL);
+ this->h->get_hash(this->h, inner, out);
+
+ /* reinit for next call */
+ this->h->get_hash(this->h, this->ipaded_key, NULL);
+ }
return SUCCESS;
}
@@ -91,13 +108,21 @@ static status_t get_mac(private_hmac_t *this, chunk_t data, u_int8_t *out)
static status_t allocate_mac(private_hmac_t *this, chunk_t data, chunk_t *out)
{
/* allocate space and use get_mac */
- out->len = this->h->get_block_size(this->h);
- out->ptr = allocator_alloc(out->len);
- if (out->ptr == NULL)
+ if (out == NULL)
{
- return OUT_OF_RES;
+ /* append mode */
+ this->public.get_mac(&(this->public), data, NULL);
+ }
+ else
+ {
+ out->len = this->h->get_block_size(this->h);
+ out->ptr = allocator_alloc(out->len);
+ if (out->ptr == NULL)
+ {
+ return OUT_OF_RES;
+ }
+ this->public.get_mac(&(this->public), data, out->ptr);
}
- this->public.get_mac(&(this->public), data, out->ptr);
return SUCCESS;
}
@@ -137,6 +162,10 @@ static status_t set_key(private_hmac_t *this, chunk_t key)
this->opaded_key.ptr[i] = buffer[i] ^ 0x5C;
}
+ /* begin hashing if inner pad */
+ this->h->reset(this->h);
+ this->h->get_hash(this->h, this->ipaded_key, NULL);
+
return SUCCESS;;
}