1 /*
2  *************************************************************************
3  * Ralink Tech Inc.
4  * 5F., No.36, Taiyuan St., Jhubei City,
5  * Hsinchu County 302,
6  * Taiwan, R.O.C.
7  *
8  * (c) Copyright 2002-2007, Ralink Technology, Inc.
9  *
10  * This program is free software; you can redistribute it and/or modify  *
11  * it under the terms of the GNU General Public License as published by  *
12  * the Free Software Foundation; either version 2 of the License, or     *
13  * (at your option) any later version.                                   *
14  *                                                                       *
15  * This program is distributed in the hope that it will be useful,       *
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18  * GNU General Public License for more details.                          *
19  *                                                                       *
20  * You should have received a copy of the GNU General Public License     *
21  * along with this program; if not, write to the                         *
22  * Free Software Foundation, Inc.,                                       *
23  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
24  *                                                                       *
25  *************************************************************************/
26 
27 #include "../crypt_hmac.h"
28 
29 #ifdef HMAC_SHA1_SUPPORT
30 /*
31 ========================================================================
32 Routine Description:
33     HMAC using SHA1 hash function
34 
35 Arguments:
36     key             Secret key
37     key_len         The length of the key in bytes
38     message         Message context
39     message_len     The length of message in bytes
40     macLen          Request the length of message authentication code
41 
42 Return Value:
43     mac             Message authentication code
44 
45 Note:
46     None
47 ========================================================================
48 */
HMAC_SHA1(IN const u8 Key[],u32 KeyLen,IN const u8 Message[],u32 MessageLen,u8 MAC[],u32 MACLen)49 void HMAC_SHA1(IN const u8 Key[],
50 	       u32 KeyLen,
51 	       IN const u8 Message[],
52 	       u32 MessageLen, u8 MAC[], u32 MACLen)
53 {
54 	struct rt_sha1_ctx sha_ctx1;
55 	struct rt_sha1_ctx sha_ctx2;
56 	u8 K0[SHA1_BLOCK_SIZE];
57 	u8 Digest[SHA1_DIGEST_SIZE];
58 	u32 index;
59 
60 	NdisZeroMemory(&sha_ctx1, sizeof(struct rt_sha1_ctx));
61 	NdisZeroMemory(&sha_ctx2, sizeof(struct rt_sha1_ctx));
62 	/*
63 	 * If the length of K = B(Block size): K0 = K.
64 	 * If the length of K > B: hash K to obtain an L byte string,
65 	 * then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00).
66 	 * If the length of K < B: append zeros to the end of K to create a B-byte string K0
67 	 */
68 	NdisZeroMemory(K0, SHA1_BLOCK_SIZE);
69 	if (KeyLen <= SHA1_BLOCK_SIZE)
70 		NdisMoveMemory(K0, Key, KeyLen);
71 	else
72 		RT_SHA1(Key, KeyLen, K0);
73 	/* End of if */
74 
75 	/* Exclusive-Or K0 with ipad */
76 	/* ipad: Inner pad; the byte x¡¦36¡¦ repeated B times. */
77 	for (index = 0; index < SHA1_BLOCK_SIZE; index++)
78 		K0[index] ^= 0x36;
79 	/* End of for */
80 
81 	RT_SHA1_Init(&sha_ctx1);
82 	/* H(K0^ipad) */
83 	SHA1_Append(&sha_ctx1, K0, sizeof(K0));
84 	/* H((K0^ipad)||text) */
85 	SHA1_Append(&sha_ctx1, Message, MessageLen);
86 	SHA1_End(&sha_ctx1, Digest);
87 
88 	/* Exclusive-Or K0 with opad and remove ipad */
89 	/* opad: Outer pad; the byte x¡¦5c¡¦ repeated B times. */
90 	for (index = 0; index < SHA1_BLOCK_SIZE; index++)
91 		K0[index] ^= 0x36 ^ 0x5c;
92 	/* End of for */
93 
94 	RT_SHA1_Init(&sha_ctx2);
95 	/* H(K0^opad) */
96 	SHA1_Append(&sha_ctx2, K0, sizeof(K0));
97 	/* H( (K0^opad) || H((K0^ipad)||text) ) */
98 	SHA1_Append(&sha_ctx2, Digest, SHA1_DIGEST_SIZE);
99 	SHA1_End(&sha_ctx2, Digest);
100 
101 	if (MACLen > SHA1_DIGEST_SIZE)
102 		NdisMoveMemory(MAC, Digest, SHA1_DIGEST_SIZE);
103 	else
104 		NdisMoveMemory(MAC, Digest, MACLen);
105 }				/* End of HMAC_SHA1 */
106 #endif /* HMAC_SHA1_SUPPORT */
107 
108 #ifdef HMAC_MD5_SUPPORT
109 /*
110 ========================================================================
111 Routine Description:
112     HMAC using MD5 hash function
113 
114 Arguments:
115     key             Secret key
116     key_len         The length of the key in bytes
117     message         Message context
118     message_len     The length of message in bytes
119     macLen          Request the length of message authentication code
120 
121 Return Value:
122     mac             Message authentication code
123 
124 Note:
125     None
126 ========================================================================
127 */
HMAC_MD5(IN const u8 Key[],u32 KeyLen,IN const u8 Message[],u32 MessageLen,u8 MAC[],u32 MACLen)128 void HMAC_MD5(IN const u8 Key[],
129 	      u32 KeyLen,
130 	      IN const u8 Message[],
131 	      u32 MessageLen, u8 MAC[], u32 MACLen)
132 {
133 	struct rt_md5_ctx_struc md5_ctx1;
134 	struct rt_md5_ctx_struc md5_ctx2;
135 	u8 K0[MD5_BLOCK_SIZE];
136 	u8 Digest[MD5_DIGEST_SIZE];
137 	u32 index;
138 
139 	NdisZeroMemory(&md5_ctx1, sizeof(struct rt_md5_ctx_struc));
140 	NdisZeroMemory(&md5_ctx2, sizeof(struct rt_md5_ctx_struc));
141 	/*
142 	 * If the length of K = B(Block size): K0 = K.
143 	 * If the length of K > B: hash K to obtain an L byte string,
144 	 * then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00).
145 	 * If the length of K < B: append zeros to the end of K to create a B-byte string K0
146 	 */
147 	NdisZeroMemory(K0, MD5_BLOCK_SIZE);
148 	if (KeyLen <= MD5_BLOCK_SIZE) {
149 		NdisMoveMemory(K0, Key, KeyLen);
150 	} else {
151 		RT_MD5(Key, KeyLen, K0);
152 	}
153 
154 	/* Exclusive-Or K0 with ipad */
155 	/* ipad: Inner pad; the byte x¡¦36¡¦ repeated B times. */
156 	for (index = 0; index < MD5_BLOCK_SIZE; index++)
157 		K0[index] ^= 0x36;
158 	/* End of for */
159 
160 	MD5_Init(&md5_ctx1);
161 	/* H(K0^ipad) */
162 	MD5_Append(&md5_ctx1, K0, sizeof(K0));
163 	/* H((K0^ipad)||text) */
164 	MD5_Append(&md5_ctx1, Message, MessageLen);
165 	MD5_End(&md5_ctx1, Digest);
166 
167 	/* Exclusive-Or K0 with opad and remove ipad */
168 	/* opad: Outer pad; the byte x¡¦5c¡¦ repeated B times. */
169 	for (index = 0; index < MD5_BLOCK_SIZE; index++)
170 		K0[index] ^= 0x36 ^ 0x5c;
171 	/* End of for */
172 
173 	MD5_Init(&md5_ctx2);
174 	/* H(K0^opad) */
175 	MD5_Append(&md5_ctx2, K0, sizeof(K0));
176 	/* H( (K0^opad) || H((K0^ipad)||text) ) */
177 	MD5_Append(&md5_ctx2, Digest, MD5_DIGEST_SIZE);
178 	MD5_End(&md5_ctx2, Digest);
179 
180 	if (MACLen > MD5_DIGEST_SIZE)
181 		NdisMoveMemory(MAC, Digest, MD5_DIGEST_SIZE);
182 	else
183 		NdisMoveMemory(MAC, Digest, MACLen);
184 }				/* End of HMAC_SHA256 */
185 #endif /* HMAC_MD5_SUPPORT */
186 
187 /* End of crypt_hmac.c */
188