xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/mvl88w8977/mlan/esa/common/sha1.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /** @file sha1.c
2  *
3  *  @brief This file defines the sha1 functions
4  *
5  * Copyright (C) 2014-2017, Marvell International Ltd.
6  *
7  * This software file (the "File") is distributed by Marvell International
8  * Ltd. under the terms of the GNU General Public License Version 2, June 1991
9  * (the "License").  You may use, redistribute and/or modify this File in
10  * accordance with the terms and conditions of the License, a copy of which
11  * is available by writing to the Free Software Foundation, Inc.,
12  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
13  * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
14  *
15  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
17  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
18  * this warranty disclaimer.
19  */
20 
21 /******************************************************
22 Change log:
23     03/07/2014: Initial version
24 ******************************************************/
25 #include "wltypes.h"
26 #include "sha1.h"
27 #include "hostsa_ext_def.h"
28 #include "authenticator.h"
29 
30 /*
31  *  Define the SHA1 circular left shift macro
32  */
33 
34 #define Mrvl_SHA1CircularShift(bits,word) \
35                 (((word) << (bits)) | ((word) >> (32-(bits))))
36 
37 /* Local Function Prototyptes */
38 static void Mrvl_SHA1PadMessage(Mrvl_SHA1_CTX *);
39 static void Mrvl_SHA1ProcessMessageBlock(Mrvl_SHA1_CTX *);
40 /*
41  *  SHA1Init
42  *
43  *  Description:
44  *      This function will initialize the SHA1_CTX in preparation
45  *      for computing a new SHA1 message digest.
46  *
47  *  Parameters:
48  *      context: [in/out]
49  *          The context to reset.
50  *
51  *  Returns:
52  *      sha Error Code.
53  *
54  */
55 /*int SHA1Init(SHA1_CTX *context) */
56 int
Mrvl_SHA1Init(Mrvl_SHA1_CTX * context)57 Mrvl_SHA1Init(Mrvl_SHA1_CTX *context)
58 {
59 	if (!context) {
60 		return shaNull;
61 	}
62 
63 	context->Length_Low = 0;
64 	context->Length_High = 0;
65 	context->Message_Block_Index = 0;
66 
67 	context->Intermediate_Hash[0] = 0x67452301;
68 	context->Intermediate_Hash[1] = 0xEFCDAB89;
69 	context->Intermediate_Hash[2] = 0x98BADCFE;
70 	context->Intermediate_Hash[3] = 0x10325476;
71 	context->Intermediate_Hash[4] = 0xC3D2E1F0;
72 
73 	context->Computed = 0;
74 	context->Corrupted = 0;
75 
76 	return shaSuccess;
77 }
78 
79 /*
80  *  SHA1Final
81  *
82  *  Description:
83  *      This function will return the 160-bit message digest into the
84  *      Message_Digest array  provided by the caller.
85  *      NOTE: The first octet of hash is stored in the 0th element,
86  *            the last octet of hash in the 19th element.
87  *
88  *  Parameters:
89  *      context: [in/out]
90  *          The context to use to calculate the SHA-1 hash.
91  *      Message_Digest: [out]
92  *          Where the digest is returned.
93  *
94  *  Returns:
95  *      sha Error Code.
96  *
97  */
98 int
Mrvl_SHA1Final(void * priv,Mrvl_SHA1_CTX * context,UINT8 Message_Digest[A_SHA_DIGEST_LEN])99 Mrvl_SHA1Final(void *priv, Mrvl_SHA1_CTX *context,
100 	       UINT8 Message_Digest[A_SHA_DIGEST_LEN])
101 {
102 	phostsa_private psapriv = (phostsa_private)priv;
103 	hostsa_util_fns *util_fns = &psapriv->util_fns;
104 	int i;
105 
106 	if (!context || !Message_Digest) {
107 		return shaNull;
108 	}
109 
110 	if (context->Corrupted) {
111 		return context->Corrupted;
112 	}
113 
114 	if (!context->Computed) {
115 		Mrvl_SHA1PadMessage(context);
116 		for (i = 0; i < 64; ++i) {
117 			/* message may be sensitive, clear it out */
118 			context->Message_Block[i] = 0;
119 		}
120 		context->Length_Low = 0;	/* and clear length */
121 		context->Length_High = 0;
122 		context->Computed = 1;
123 
124 	}
125 
126 	for (i = 0; i < A_SHA_DIGEST_LEN; ++i) {
127 		Message_Digest[i] = context->Intermediate_Hash[i >> 2]
128 			>> 8 * (3 - (i & 0x03));
129 	}
130 
131 	memset(util_fns, context, 0x00, sizeof(Mrvl_SHA1_CTX));
132 
133 	return shaSuccess;
134 }
135 
136 /*
137  *  SHA1Update
138  *
139  *  Description:
140  *      This function accepts an array of octets as the next portion
141  *      of the message.
142  *
143  *  Parameters:
144  *      context: [in/out]
145  *          The SHA context to update
146  *      message_array: [in]
147  *          An array of characters representing the next portion of
148  *          the message.
149  *      length: [in]
150  *          The length of the message in message_array
151  *
152  *  Returns:
153  *      sha Error Code.
154  *
155  */
156 int
Mrvl_SHA1Update(Mrvl_SHA1_CTX * context,const UINT8 * message_array,unsigned length)157 Mrvl_SHA1Update(Mrvl_SHA1_CTX *context,
158 		const UINT8 *message_array, unsigned length)
159 {
160 	if (!length) {
161 		return shaSuccess;
162 	}
163 
164 	if (!context || !message_array) {
165 		return shaNull;
166 	}
167 
168 	if (context->Computed) {
169 		context->Corrupted = shaStateError;
170 
171 		return shaStateError;
172 	}
173 
174 	if (context->Corrupted) {
175 		return context->Corrupted;
176 	}
177 	while (length-- && !context->Corrupted) {
178 		context->Message_Block[context->Message_Block_Index++] =
179 			(*message_array & 0xFF);
180 
181 		context->Length_Low += 8;
182 		if (context->Length_Low == 0) {
183 			context->Length_High++;
184 			if (context->Length_High == 0) {
185 				/* Message is too long */
186 				context->Corrupted = 1;
187 			}
188 		}
189 
190 		if (context->Message_Block_Index == 64) {
191 			Mrvl_SHA1ProcessMessageBlock(context);
192 		}
193 
194 		message_array++;
195 	}
196 
197 	return shaSuccess;
198 }
199 
200 /*
201  *  SHA1ProcessMessageBlock
202  *
203  *  Description:
204  *      This function will process the next 512 bits of the message
205  *      stored in the Message_Block array.
206  *
207  *  Parameters:
208  *      None.
209  *
210  *  Returns:
211  *      Nothing.
212  *
213  *  Comments:
214 
215 
216 
217 Eastlake & Jones             Informational                     [Page 14]
218 
219 RFC 3174           US Secure Hash Algorithm 1 (SHA1)      September 2001
220 
221 
222  *      Many of the variable names in this code, especially the
223  *      single character names, were used because those were the
224  *      names used in the publication.
225  *
226  *
227  */
228 
229 #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
230 
231 /* blk0() and blk() perform the initial expand. */
232 /* I got the idea of expanding during the round function from SSLeay */
233 #define blk(i) (W[i&15] = rol(W[(i+13)&15]^W[(i+8)&15]^W[(i+2)&15]^W[i&15],1))
234 #define blk0(i) ((i & 0x30)? blk(i) : W[i])
235 
236 /*
237 NOte- Some of the variables are made static in this file because
238 this function runs in the idle task. The idle task dosent have
239 enough stack space to accomodate these variables. In the future
240 if this function is run in a different task with large stack space
241 or if the stack space of the idle task is increased then we can
242 remove the static defination from these variables.
243 */
244 void
Mrvl_SHA1ProcessMessageBlock(Mrvl_SHA1_CTX * context)245 Mrvl_SHA1ProcessMessageBlock(Mrvl_SHA1_CTX *context)
246 {
247 	static const UINT32 K[] = {	/* Constants defined in SHA-1   */
248 		0x5A827999,
249 		0x6ED9EBA1,
250 		0x8F1BBCDC,
251 		0xCA62C1D6
252 	};
253 	int t;			/* Loop counter                */
254 	UINT32 temp;		/* Temporary word value        */
255 	UINT32 *W;
256 	UINT32 A, B, C, D, E;	/* Word buffers                */
257 
258 	/* WLAN buffers are aligned, so the context starts at a UINT32 boundary */
259 	W = context->Scratch;
260 
261 	for (t = 0; t < 16; t++) {
262 		W[t] = context->Message_Block[t * 4] << 24;
263 		W[t] |= context->Message_Block[t * 4 + 1] << 16;
264 		W[t] |= context->Message_Block[t * 4 + 2] << 8;
265 		W[t] |= context->Message_Block[t * 4 + 3];
266 	}
267 
268 	A = context->Intermediate_Hash[0];
269 	B = context->Intermediate_Hash[1];
270 	C = context->Intermediate_Hash[2];
271 	D = context->Intermediate_Hash[3];
272 	E = context->Intermediate_Hash[4];
273 
274 	for (t = 0; t < 20; t++) {
275 		temp = Mrvl_SHA1CircularShift(5, A) +
276 			((B & C) | ((~B) & D)) + E + blk0(t) + K[0];
277 		E = D;
278 		D = C;
279 		C = Mrvl_SHA1CircularShift(30, B);
280 
281 		B = A;
282 		A = temp;
283 	}
284 
285 	for (t = 20; t < 40; t++) {
286 		temp = Mrvl_SHA1CircularShift(5,
287 					      A) + (B ^ C ^ D) + E + blk(t) +
288 			K[1];
289 		E = D;
290 		D = C;
291 		C = Mrvl_SHA1CircularShift(30, B);
292 		B = A;
293 		A = temp;
294 	}
295 
296 	for (t = 40; t < 60; t++) {
297 		temp = Mrvl_SHA1CircularShift(5, A) +
298 			((B & C) | (B & D) | (C & D)) + E + blk(t) + K[2];
299 		E = D;
300 		D = C;
301 		C = Mrvl_SHA1CircularShift(30, B);
302 		B = A;
303 		A = temp;
304 	}
305 
306 	for (t = 60; t < 80; t++) {
307 		temp = Mrvl_SHA1CircularShift(5,
308 					      A) + (B ^ C ^ D) + E + blk(t) +
309 			K[3];
310 		E = D;
311 		D = C;
312 		C = Mrvl_SHA1CircularShift(30, B);
313 		B = A;
314 		A = temp;
315 	}
316 
317 	context->Intermediate_Hash[0] += A;
318 	context->Intermediate_Hash[1] += B;
319 	context->Intermediate_Hash[2] += C;
320 	context->Intermediate_Hash[3] += D;
321 	context->Intermediate_Hash[4] += E;
322 
323 	context->Message_Block_Index = 0;
324 }
325 
326 /*
327  *  SHA1PadMessage
328  *
329 
330 
331 
332 Eastlake & Jones             Informational                     [Page 16]
333 
334 RFC 3174           US Secure Hash Algorithm 1 (SHA1)      September 2001
335 
336 
337  *  Description:
338  *      According to the standard, the message must be padded to an even
339  *      512 bits.  The first padding bit must be a '1'.  The last 64
340  *      bits represent the length of the original message.  All bits in
341  *      between should be 0.  This function will pad the message
342  *      according to those rules by filling the Message_Block array
343  *      accordingly.  It will also call the ProcessMessageBlock function
344  *      provided appropriately.  When it returns, it can be assumed that
345  *      the message digest has been computed.
346  *
347  *  Parameters:
348  *      context: [in/out]
349  *          The context to pad
350  *      ProcessMessageBlock: [in]
351  *          The appropriate SHA*ProcessMessageBlock function
352  *  Returns:
353  *      Nothing.
354  *
355  */
356 
357 void
Mrvl_SHA1PadMessage(Mrvl_SHA1_CTX * context)358 Mrvl_SHA1PadMessage(Mrvl_SHA1_CTX *context)
359 {
360 	/*
361 	 *  Check to see if the current message block is too small to hold
362 	 *  the initial padding bits and length.  If so, we will pad the
363 	 *  block, process it, and then continue padding into a second
364 	 *  block.
365 	 */
366 	if (context->Message_Block_Index > 55) {
367 		context->Message_Block[context->Message_Block_Index++] = 0x80;
368 		while (context->Message_Block_Index < 64) {
369 			context->Message_Block[context->Message_Block_Index++] =
370 				0;
371 		}
372 
373 		Mrvl_SHA1ProcessMessageBlock(context);
374 
375 		while (context->Message_Block_Index < 56) {
376 			context->Message_Block[context->Message_Block_Index++] =
377 				0;
378 		}
379 	} else {
380 		context->Message_Block[context->Message_Block_Index++] = 0x80;
381 		while (context->Message_Block_Index < 56) {
382 
383 			context->Message_Block[context->Message_Block_Index++] =
384 				0;
385 		}
386 	}
387 
388 	/*
389 	 *  Store the message length as the last 8 octets
390 	 */
391 	context->Message_Block[56] = context->Length_High >> 24;
392 	context->Message_Block[57] = context->Length_High >> 16;
393 	context->Message_Block[58] = context->Length_High >> 8;
394 	context->Message_Block[59] = context->Length_High;
395 	context->Message_Block[60] = context->Length_Low >> 24;
396 	context->Message_Block[61] = context->Length_Low >> 16;
397 	context->Message_Block[62] = context->Length_Low >> 8;
398 	context->Message_Block[63] = context->Length_Low;
399 
400 	Mrvl_SHA1ProcessMessageBlock(context);
401 }
402