diff options
author | Niels Möller <nisse@lysator.liu.se> | 2002-01-11 14:33:53 +0100 |
---|---|---|
committer | Niels Möller <nisse@lysator.liu.se> | 2002-01-11 14:33:53 +0100 |
commit | 7699f2d5609387e16461b46ad7687685e0d9a43b (patch) | |
tree | 8fe48a574156f3bc37d4bbee42716ead38208edb /hmac.c | |
parent | cf5ba848d9c08b1d2725f0ee32da778766ec69bd (diff) | |
download | nettle-7699f2d5609387e16461b46ad7687685e0d9a43b.tar.gz |
New files.
Rev: src/nettle/hmac-md5.c:1.1
Rev: src/nettle/hmac.c:1.1
Rev: src/nettle/hmac.h:1.1
Rev: src/nettle/md5-meta.c:1.1
Rev: src/nettle/nettle-meta.h:1.1
Rev: src/nettle/sha1-meta.c:1.1
Rev: src/nettle/sha256-meta.c:1.1
Diffstat (limited to 'hmac.c')
-rw-r--r-- | hmac.c | 90 |
1 files changed, 90 insertions, 0 deletions
@@ -0,0 +1,90 @@ +/* hmac.c + * + * HMAC message authentication code. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The nettle library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the nettle library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#include "hmac.h" + +#include "memxor.h" + +#include <assert.h> + +#define IPAD 0x36 +#define OPAD 0x5c + +void +hmac_init(void *outer, void *inner, void *state, + struct hmac_info *info, + unsigned key_length, const uint8_t *key) +{ + uint8_t pad = alloca(info->block_size); + + info->init(outer); + info->init(inner); + + if (length > info->block_size) + { + /* Reduce key to the algorithm's hash size. Use the area pointed + * to by state for the temporary state. */ + + uint8_t *digest = alloca(info->digest_size); + + info->init(state); + info->update(state, key_length, key); + info->digest(state, info->digest_size, digest); + + key = digest; + key_length = info->digest_size; + } + + assert(key_size <= info->block_size); + + memset(pad, OPAD, info->block_size); + memxor(pad, key, key_length); + + info->update(outer, info->block_size, pad); + + memset(pad, IPAD, info->block_size); + memxor(pad, key, key_length); + + info->update(inner, info->block_size, pad); + + memcpy(state, inner, info->ctx_size); +} + +void +hmac_digest(void *outer, void *inner, void *state + struct hmac_info *info, + unsigned length, uint8_t *dst) +{ + uint8_t *digest = alloca(info->digest_size); + + info->digest(state, info->digest_size, digest); + + memcpy(outer, state, info->ctx_size); + + info->update(state, info->digest_size, digest); + info->digest(state, length, dst); + + memcpy(state, inner, info->ctx_size); +} |