1/* 2 * Function: hmac_md5 3 * From rfc2104.txt 4 * 5 * $Id: hmac.c 241182 2011-02-17 21:50:03Z $ 6 */ 7 8/* 9 * Copyright (C) The Internet Society (2001). All Rights Reserved. 10 * 11 * This document and translations of it may be copied and furnished to 12 * others, and derivative works that comment on or otherwise explain it 13 * or assist in its implementation may be prepared, copied, published 14 * and distributed, in whole or in part, without restriction of any 15 * kind, provided that the above copyright notice and this paragraph are 16 * included on all such copies and derivative works. However, this 17 * document itself may not be modified in any way, such as by removing 18 * the copyright notice or references to the Internet Society or other 19 * Internet organizations, except as needed for the purpose of 20 * developing Internet standards in which case the procedures for 21 * copyrights defined in the Internet Standards process must be 22 * followed, or as required to translate it into languages other than 23 * English. 24 * 25 * The limited permissions granted above are perpetual and will not be 26 * revoked by the Internet Society or its successors or assigns. 27 * 28 * This document and the information contained herein is provided on an 29 * "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING 30 * TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING 31 * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION 32 * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF 33 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 34 * 35 * Copyright (C) 2015, Broadcom Corporation 36 * All Rights Reserved. 37 * 38 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; 39 * the contents of this file may not be disclosed to third parties, copied 40 * or duplicated in any form, in whole or in part, without the prior 41 * written permission of Broadcom Corporation. 42 * 43 * $Id: hmac.c 241182 2011-02-17 21:50:03Z $ 44 */ 45 46 47#include <bcmcrypto/md5.h> 48 49#ifdef BCMDRIVER 50#include <osl.h> 51#else 52#include <string.h> 53#endif /* BCMDRIVER */ 54 55#if defined(BCMDRIVER) && defined(HNDRTE) && !defined(BCMSUP_PSK) 56#error "BCMSUP_PSK or BCMCCX must be defined to compile hmac.c for driver!" 57#endif 58 59extern void BCMROMFN(hmac_md5)(unsigned char *text, int text_len, unsigned char *key, 60 int key_len, unsigned char *digest); 61 62/* text pointer to data stream */ 63/* text_len length of data stream */ 64/* key pointer to authentication key */ 65/* key_len length of authentication key */ 66/* digest caller digest to be filled in */ 67void 68BCMROMFN(hmac_md5)(unsigned char *text, int text_len, unsigned char *key, 69 int key_len, unsigned char *digest) 70{ 71 MD5_CTX context; 72 unsigned char k_ipad[65]; /* inner padding - 73 * key XORd with ipad 74 */ 75 unsigned char k_opad[65]; /* outer padding - 76 * key XORd with opad 77 */ 78 unsigned char tk[16]; 79 int i; 80 81 /* if key is longer than 64 bytes reset it to key=MD5(key) */ 82 if (key_len > 64) { 83 MD5_CTX tctx; 84 85 MD5Init(&tctx); 86 MD5Update(&tctx, key, key_len); 87 MD5Final(tk, &tctx); 88 89 key = tk; 90 key_len = 16; 91 } 92 93 /* 94 * the HMAC_MD5 transform looks like: 95 * 96 * MD5(K XOR opad, MD5(K XOR ipad, text)) 97 * 98 * where K is an n byte key 99 * ipad is the byte 0x36 repeated 64 times 100 101 * opad is the byte 0x5c repeated 64 times 102 * and text is the data being protected 103 */ 104 105 /* start out by storing key in pads */ 106 memset(k_ipad, 0, sizeof(k_ipad)); 107 memset(k_opad, 0, sizeof(k_opad)); 108 memcpy(k_ipad, key, key_len); 109 memcpy(k_opad, key, key_len); 110 111 /* XOR key with ipad and opad values */ 112 for (i = 0; i < 64; i++) { 113 k_ipad[i] ^= 0x36; 114 k_opad[i] ^= 0x5c; 115 } 116 /* 117 * perform inner MD5 118 */ 119 MD5Init(&context); /* init context for 1st pass */ 120 MD5Update(&context, k_ipad, 64); /* start with inner pad */ 121 MD5Update(&context, text, text_len); /* then text of datagram */ 122 MD5Final(digest, &context); /* finish up 1st pass */ 123 /* 124 * perform outer MD5 125 */ 126 MD5Init(&context); /* init context for 2nd pass */ 127 MD5Update(&context, k_opad, 64); /* start with outer pad */ 128 MD5Update(&context, digest, 16); /* then results of 1st hash */ 129 MD5Final(digest, &context); /* finish up 2nd pass */ 130} 131