📄 md5.c
字号:
/* *************************************************************************** * Ralink Tech Inc. * 4F, No. 2 Technology 5th Rd. * Science-based Industrial Park * Hsin-chu, Taiwan, R.O.C. * * (c) Copyright 2002-2006, Ralink Technology, Inc. * * All rights reserved. Ralink's source code is an unpublished work and the * use of a copyright notice does not imply otherwise. This source code * contains confidential trade secret material of Ralink Tech. Any attemp * or participation in deciphering, decoding, reverse engineering or in any * way altering the source code is stricitly prohibited, unless the prior * written consent of Ralink Technology, Inc. is obtained. *************************************************************************** Module Name: md5.c Abstract: Revision History: Who When What -------- ---------- ---------------------------------------------- Name Date Modification logs jan 10-28-03 Initial Rita 11-23-04 Modify MD5 and SHA-1 Rita 10-14-05 Modify SHA-1 in big-endian platform */#include "rt_config.h"/** * md5_mac: * @key: pointer to the key used for MAC generation * @key_len: length of the key in bytes * @data: pointer to the data area for which the MAC is generated * @data_len: length of the data in bytes * @mac: pointer to the buffer holding space for the MAC; the buffer should * have space for 128-bit (16 bytes) MD5 hash value * * md5_mac() determines the message authentication code by using secure hash * MD5(key | data | key). */void md5_mac(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac){ MD5_CTX context; MD5Init(&context); MD5Update(&context, key, key_len); MD5Update(&context, data, data_len); MD5Update(&context, key, key_len); MD5Final(mac, &context);}/** * hmac_md5: * @key: pointer to the key used for MAC generation * @key_len: length of the key in bytes * @data: pointer to the data area for which the MAC is generated * @data_len: length of the data in bytes * @mac: pointer to the buffer holding space for the MAC; the buffer should * have space for 128-bit (16 bytes) MD5 hash value * * hmac_md5() determines the message authentication code using HMAC-MD5. * This implementation is based on the sample code presented in RFC 2104. */void hmac_md5(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac){ MD5_CTX context; u8 k_ipad[65]; /* inner padding - key XORd with ipad */ u8 k_opad[65]; /* outer padding - key XORd with opad */ u8 tk[16]; int i; //assert(key != NULL && data != NULL && mac != NULL); /* if key is longer than 64 bytes reset it to key = MD5(key) */ if (key_len > 64) { MD5_CTX ttcontext; MD5Init(&ttcontext); MD5Update(&ttcontext, key, key_len); MD5Final(tk, &ttcontext); //key=(PUCHAR)ttcontext.buf; key = tk; key_len = 16; } /* the HMAC_MD5 transform looks like: * * MD5(K XOR opad, MD5(K XOR ipad, text)) * * where K is an n byte key * ipad is the byte 0x36 repeated 64 times * opad is the byte 0x5c repeated 64 times * and text is the data being protected */ /* start out by storing key in pads */ NdisZeroMemory(k_ipad, sizeof(k_ipad)); NdisZeroMemory(k_opad, sizeof(k_opad)); //assert(key_len < sizeof(k_ipad)); NdisMoveMemory(k_ipad, key, key_len); NdisMoveMemory(k_opad, key, key_len); /* XOR key with ipad and opad values */ for (i = 0; i < 64; i++) { k_ipad[i] ^= 0x36; k_opad[i] ^= 0x5c; } /* perform inner MD5 */ MD5Init(&context); /* init context for 1st pass */ MD5Update(&context, k_ipad, 64); /* start with inner pad */ MD5Update(&context, data, data_len); /* then text of datagram */ MD5Final(mac, &context); /* finish up 1st pass */ /* perform outer MD5 */ MD5Init(&context); /* init context for 2nd pass */ MD5Update(&context, k_opad, 64); /* start with outer pad */ MD5Update(&context, mac, 16); /* then results of 1st hash */ MD5Final(mac, &context); /* finish up 2nd pass */}#ifndef BIG_ENDIAN#define byteReverse(buf, len) /* Nothing */#elsevoid byteReverse(unsigned char *buf, unsigned longs);void byteReverse(unsigned char *buf, unsigned longs){ do { *(ULONG *)buf = SWAP32(*(ULONG *)buf); buf += 4; } while (--longs);}#endif/* ========================== MD5 implementation =========================== */ // four base functions for MD5 #define MD5_F1(x, y, z) (((x) & (y)) | ((~x) & (z))) #define MD5_F2(x, y, z) (((x) & (z)) | ((y) & (~z))) #define MD5_F3(x, y, z) ((x) ^ (y) ^ (z))#define MD5_F4(x, y, z) ((y) ^ ((x) | (~z)))#define CYCLIC_LEFT_SHIFT(w, s) (((w) << (s)) | ((w) >> (32-(s))))#define MD5Step(f, w, x, y, z, data, t, s) \ ( w += f(x, y, z) + data + t, w = (CYCLIC_LEFT_SHIFT(w, s)) & 0xffffffff, w += x )/* * Function Description: * Initiate MD5 Context satisfied in RFC 1321 * * Arguments: * pCtx Pointer to MD5 context * * Return Value: * None */VOID MD5Init(MD5_CTX *pCtx){ pCtx->Buf[0]=0x67452301; pCtx->Buf[1]=0xefcdab89; pCtx->Buf[2]=0x98badcfe; pCtx->Buf[3]=0x10325476; pCtx->LenInBitCount[0]=0; pCtx->LenInBitCount[1]=0;}/* * Function Description: * Update MD5 Context, allow of an arrary of octets as the next portion * of the message * * Arguments: * pCtx Pointer to MD5 context * pData Pointer to input data * LenInBytes The length of input data (unit: byte) * * Return Value: * None * * Note: * Called after MD5Init or MD5Update(itself) */VOID MD5Update(MD5_CTX *pCtx, UCHAR *pData, ULONG LenInBytes){ ULONG TfTimes; ULONG temp; unsigned int i; temp = pCtx->LenInBitCount[0]; pCtx->LenInBitCount[0] = (ULONG) (pCtx->LenInBitCount[0] + (LenInBytes << 3)); if (pCtx->LenInBitCount[0] < temp) pCtx->LenInBitCount[1]++; //carry in pCtx->LenInBitCount[1] += LenInBytes >> 29; // mod 64 bytes temp = (temp >> 3) & 0x3f; // process lacks of 64-byte data if (temp) { UCHAR *pAds = (UCHAR *) pCtx->Input + temp; if ((temp+LenInBytes) < 64) { NdisMoveMemory(pAds, (UCHAR *)pData, LenInBytes); return; } NdisMoveMemory(pAds, (UCHAR *)pData, 64-temp); byteReverse(pCtx->Input, 16); MD5Transform(pCtx->Buf, (ULONG *)pCtx->Input); pData += 64-temp; LenInBytes -= 64-temp; } // end of if (temp) TfTimes = (LenInBytes >> 6); for (i=TfTimes; i>0; i--) { NdisMoveMemory(pCtx->Input, (UCHAR *)pData, 64); byteReverse(pCtx->Input, 16); MD5Transform(pCtx->Buf, (ULONG *)pCtx->Input); pData += 64; LenInBytes -= 64; } // end of for // buffering lacks of 64-byte data if(LenInBytes) NdisMoveMemory(pCtx->Input, (UCHAR *)pData, LenInBytes); }/* * Function Description: * Append padding bits and length of original message in the tail * The message digest has to be completed in the end * * Arguments: * Digest Output of Digest-Message for MD5 * pCtx Pointer to MD5 context * * Return Value: * None * * Note: * Called after MD5Update */VOID MD5Final(UCHAR Digest[16], MD5_CTX *pCtx){ UCHAR Remainder; UCHAR PadLenInBytes; UCHAR *pAppend=0; unsigned int i; Remainder = (UCHAR)((pCtx->LenInBitCount[0] >> 3) & 0x3f); PadLenInBytes = (Remainder < 56) ? (56-Remainder) : (120-Remainder); pAppend = (UCHAR *)pCtx->Input + Remainder; // padding bits without crossing block(64-byte based) boundary if (Remainder < 56) { *pAppend = 0x80; PadLenInBytes --; NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, PadLenInBytes); // add data-length field, from low to high for (i=0; i<4; i++) { pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[0] >> (i << 3)) & 0xff); pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[1] >> (i << 3)) & 0xff); } byteReverse(pCtx->Input, 16); MD5Transform(pCtx->Buf, (ULONG *)pCtx->Input); } // end of if // padding bits with crossing block(64-byte based) boundary else { // the first block === *pAppend = 0x80; PadLenInBytes --; NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, (64-Remainder-1)); PadLenInBytes -= (64 - Remainder - 1); byteReverse(pCtx->Input, 16); MD5Transform(pCtx->Buf, (ULONG *)pCtx->Input); // the second block === NdisZeroMemory((UCHAR *)pCtx->Input, PadLenInBytes); // add data-length field for (i=0; i<4; i++) { pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[0] >> (i << 3)) & 0xff); pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[1] >> (i << 3)) & 0xff); } byteReverse(pCtx->Input, 16); MD5Transform(pCtx->Buf, (ULONG *)pCtx->Input); } // end of else NdisMoveMemory((UCHAR *)Digest, (ULONG *)pCtx->Buf, 16); // output byteReverse((UCHAR *)Digest, 4); NdisZeroMemory(pCtx, sizeof(pCtx)); // memory free }/* * Function Description: * The central algorithm of MD5, consists of four rounds and sixteen * steps per round * * Arguments: * Buf Buffers of four states (output: 16 bytes) * Mes Input data (input: 64 bytes) * * Return Value: * None * * Note: * Called by MD5Update or MD5Final */VOID MD5Transform(ULONG Buf[4], ULONG Mes[16]){ ULONG Reg[4], Temp; unsigned int i; static UCHAR LShiftVal[16] = { 7, 12, 17, 22, 5, 9 , 14, 20, 4, 11, 16, 23, 6, 10, 15, 21, }; // [equal to 4294967296*abs(sin(index))] static ULONG MD5Table[64] = { 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 }; for (i=0; i<4; i++) Reg[i]=Buf[i]; // 64 steps in MD5 algorithm for (i=0; i<16; i++) { MD5Step(MD5_F1, Reg[0], Reg[1], Reg[2], Reg[3], Mes[i], MD5Table[i], LShiftVal[i & 0x3]); // one-word right shift Temp = Reg[3]; Reg[3] = Reg[2]; Reg[2] = Reg[1]; Reg[1] = Reg[0]; Reg[0] = Temp; } for (i=16; i<32; i++) { MD5Step(MD5_F2, Reg[0], Reg[1], Reg[2], Reg[3], Mes[(5*(i & 0xf)+1) & 0xf], MD5Table[i], LShiftVal[(0x1 << 2)+(i & 0x3)]); // one-word right shift Temp = Reg[3]; Reg[3] = Reg[2]; Reg[2] = Reg[1]; Reg[1] = Reg[0]; Reg[0] = Temp; } for (i=32; i<48; i++) { MD5Step(MD5_F3, Reg[0], Reg[1], Reg[2], Reg[3], Mes[(3*(i & 0xf)+5) & 0xf], MD5Table[i], LShiftVal[(0x1 << 3)+(i & 0x3)]); // one-word right shift Temp = Reg[3]; Reg[3] = Reg[2]; Reg[2] = Reg[1]; Reg[1] = Reg[0]; Reg[0] = Temp; } for (i=48; i<64; i++) { MD5Step(MD5_F4, Reg[0], Reg[1], Reg[2], Reg[3], Mes[(7*(i & 0xf)) & 0xf], MD5Table[i], LShiftVal[(0x3 << 2)+(i & 0x3)]); // one-word right shift Temp = Reg[3]; Reg[3] = Reg[2]; Reg[2] = Reg[1]; Reg[1] = Reg[0]; Reg[0] = Temp; } // (temporary)output for (i=0; i<4; i++) Buf[i] += Reg[i];}/* ========================= SHA-1 implementation ========================== */// four base functions for SHA-1#define SHA1_F1(b, c, d) (((b) & (c)) | ((~b) & (d))) #define SHA1_F2(b, c, d) ((b) ^ (c) ^ (d)) #define SHA1_F3(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))#define SHA1Step(f, a, b, c, d, e, w, k) \ ( e += ( f(b, c, d) + w + k + CYCLIC_LEFT_SHIFT(a, 5)) & 0xffffffff, \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -