diff options
Diffstat (limited to 'Source/charon/transforms')
-rw-r--r-- | Source/charon/transforms/hmac.c | 61 | ||||
-rw-r--r-- | Source/charon/transforms/hmac.h | 10 |
2 files changed, 55 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;; } diff --git a/Source/charon/transforms/hmac.h b/Source/charon/transforms/hmac.h index 14cec6818..25b59d0b5 100644 --- a/Source/charon/transforms/hmac.h +++ b/Source/charon/transforms/hmac.h @@ -37,6 +37,11 @@ struct hmac_s { /** * @brief Generate message authentication code. * + * If buffer is NULL, no result is given back. A next call will + * append the data to already supplied. If buffer is not NULL, + * the mac of all apended data is calculated, returned and the + * state of the hmac_t reset; + * * @param this calling hmac * @param data chunk of data to authenticate * @param [out]buffer pointer where the generated bytes will be written @@ -49,6 +54,11 @@ struct hmac_s { * @brief Generates message authentication code and * allocate space for them. * + * If chunk is NULL, no result is given back. A next call will + * append the data to already supplied. If chunk is not NULL, + * the mac of all apended data is calculated, returned and the + * state of the hmac_t reset; + * * @param this calling hmac * @param data chunk of data to authenticate * @param [out]chunk chunk which will hold generated bytes |