diff options
Diffstat (limited to 'dhcpcd/crypt/hmac_md5.c')
-rw-r--r-- | dhcpcd/crypt/hmac_md5.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/dhcpcd/crypt/hmac_md5.c b/dhcpcd/crypt/hmac_md5.c new file mode 100644 index 00000000..06ea465a --- /dev/null +++ b/dhcpcd/crypt/hmac_md5.c @@ -0,0 +1,86 @@ +/* + * dhcpcd - DHCP client daemon + * Copyright (c) 2006-2014 Roy Marples <roy@marples.name> + * All rights reserved + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <inttypes.h> +#include <string.h> + +#include "crypt.h" + +#ifdef HAVE_MD5_H +#include <md5.h> +#else +#include "md5.h" +#endif + +#define HMAC_PAD_LEN 64 +#define IPAD 0x36 +#define OPAD 0x5C + +/* hmac_md5 as per RFC3118 */ +void +hmac_md5(const uint8_t *text, int text_len, + const uint8_t *key, int key_len, + uint8_t *digest) +{ + uint8_t k_ipad[HMAC_PAD_LEN], k_opad[HMAC_PAD_LEN]; + uint8_t tk[MD5_DIGEST_LENGTH]; + int i; + MD5_CTX context; + + /* Ensure key is no bigger than HMAC_PAD_LEN */ + if (key_len > HMAC_PAD_LEN) { + MD5Init(&context); + MD5Update(&context, key, key_len); + MD5Final(tk, &context); + key = tk; + key_len = MD5_DIGEST_LENGTH; + } + + /* store key in pads */ + memcpy(k_ipad, key, key_len); + memcpy(k_opad, key, key_len); + memset(k_ipad + key_len, 0, sizeof(k_ipad) - key_len); + memset(k_opad + key_len, 0, sizeof(k_opad) - key_len); + + /* XOR key with ipad and opad values */ + for (i = 0; i < HMAC_PAD_LEN; i++) { + k_ipad[i] ^= IPAD; + k_opad[i] ^= OPAD; + } + + /* inner MD5 */ + MD5Init(&context); + MD5Update(&context, k_ipad, HMAC_PAD_LEN); + MD5Update(&context, text, text_len); + MD5Final(digest, &context); + + /* outer MD5 */ + MD5Init(&context); + MD5Update(&context, k_opad, HMAC_PAD_LEN); + MD5Update(&context, digest, MD5_DIGEST_LENGTH); + MD5Final(digest, &context); +} |