1 #include <sys/cdefs.h> 2 __RCSID("$NetBSD: hmac_md5.c,v 1.7 2015/03/27 11:33:47 roy Exp $"); 3 4 /* 5 * dhcpcd - DHCP client daemon 6 * Copyright (c) 2006-2015 Roy Marples <roy@marples.name> 7 * All rights reserved 8 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31 #include <inttypes.h> 32 #include <string.h> 33 34 #include "crypt.h" 35 36 #include "../config.h" 37 #ifdef HAVE_MD5_H 38 # ifndef DEPGEN 39 # include <md5.h> 40 # endif 41 #else 42 # include "md5.h" 43 #endif 44 45 #define HMAC_PAD_LEN 64 46 #define IPAD 0x36 47 #define OPAD 0x5C 48 49 /* hmac_md5 as per RFC3118 */ 50 void 51 hmac_md5(const uint8_t *text, size_t text_len, 52 const uint8_t *key, size_t key_len, 53 uint8_t *digest) 54 { 55 uint8_t k_ipad[HMAC_PAD_LEN], k_opad[HMAC_PAD_LEN]; 56 uint8_t tk[MD5_DIGEST_LENGTH]; 57 int i; 58 MD5_CTX context; 59 60 /* Ensure key is no bigger than HMAC_PAD_LEN */ 61 if (key_len > HMAC_PAD_LEN) { 62 MD5Init(&context); 63 MD5Update(&context, key, (unsigned int)key_len); 64 MD5Final(tk, &context); 65 key = tk; 66 key_len = MD5_DIGEST_LENGTH; 67 } 68 69 /* store key in pads */ 70 memcpy(k_ipad, key, key_len); 71 memcpy(k_opad, key, key_len); 72 memset(k_ipad + key_len, 0, sizeof(k_ipad) - key_len); 73 memset(k_opad + key_len, 0, sizeof(k_opad) - key_len); 74 75 /* XOR key with ipad and opad values */ 76 for (i = 0; i < HMAC_PAD_LEN; i++) { 77 k_ipad[i] ^= IPAD; 78 k_opad[i] ^= OPAD; 79 } 80 81 /* inner MD5 */ 82 MD5Init(&context); 83 MD5Update(&context, k_ipad, HMAC_PAD_LEN); 84 MD5Update(&context, text, (unsigned int)text_len); 85 MD5Final(digest, &context); 86 87 /* outer MD5 */ 88 MD5Init(&context); 89 MD5Update(&context, k_opad, HMAC_PAD_LEN); 90 MD5Update(&context, digest, MD5_DIGEST_LENGTH); 91 MD5Final(digest, &context); 92 } 93