xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/mvl88w8977/mlan/esa/common/sha256.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /** @file sha_256.c
2  *
3  *  @brief This file defines the SHA256 hash implementation and interface 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 /*
26  * SHA-256 hash implementation and interface functions
27  *
28  * Copyright ?2003-2006, Jouni Malinen <jkmaline@cc.hut.fi>
29  *
30  * Copyright ?2006-2007, Marvell International Ltd. and its affiliates
31  * All rights reserved.
32  *
33  * 1. Redistributions in binary form must reproduce the above copyright
34  * notice, this list of conditions and the following disclaimer in the
35  * documentation and/or other materials provided with the distribution.
36  * 2. Neither the name of Jouni Malinen, Marvell nor the names of its
37  * contributors may be used to endorse or promote products derived from
38  * this software without specific prior written permission.
39  *
40  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
41  * ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
42  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
43  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
44  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
46  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
47  * DATA, OR PROFITS; OR BUSINESS  INTERRUPTION) HOWEVER CAUSED AND ON ANY
48  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
50  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51  */
52 #include "sha_256.h"
53 #include "hostsa_ext_def.h"
54 #include "authenticator.h"
55 
56 #define WPA_GET_BE32(a) ((((UINT32) (a)[0]) << 24) |                    \
57                          (((UINT32) (a)[1]) << 16) |                    \
58                          (((UINT32) (a)[2]) << 8)  |                    \
59                          ((UINT32) (a)[3]))
60 
61 #define WPA_PUT_BE32(a, val)                          \
62     do {                                              \
63         (a)[0] = (UINT8) (((UINT32) (val)) >> 24);    \
64         (a)[1] = (UINT8) (((UINT32) (val)) >> 16);    \
65         (a)[2] = (UINT8) (((UINT32) (val)) >> 8);     \
66         (a)[3] = (UINT8) (((UINT32) (val)) & 0xff);   \
67     } while (0)
68 
69 #define WPA_PUT_BE64(a, val)                          \
70     do {                                              \
71         (a)[0] = (UINT8) (((UINT64) (val)) >> 56);    \
72         (a)[1] = (UINT8) (((UINT64) (val)) >> 48);    \
73         (a)[2] = (UINT8) (((UINT64) (val)) >> 40);    \
74         (a)[3] = (UINT8) (((UINT64) (val)) >> 32);    \
75         (a)[4] = (UINT8) (((UINT64) (val)) >> 24);    \
76         (a)[5] = (UINT8) (((UINT64) (val)) >> 16);    \
77         (a)[6] = (UINT8) (((UINT64) (val)) >> 8);     \
78         (a)[7] = (UINT8) (((UINT64) (val)) & 0xff);   \
79     } while (0)
80 
81 /**
82  * @brief	hmac_sha256_vector - HMAC-SHA256 over data vector (RFC 2104)
83  * @param priv	pointer to previous element
84  * @param key: Key for HMAC operations
85  * @param key_len: Length of the key in bytes
86  * @param num_elem: Number of elements in the data vector; including [0] spare
87  * @param addr: Pointers to the data areas, [0] element must be left as spare
88  * @param len: Lengths of the data blocks, [0] element must be left as spare
89  * @param mac: Buffer for the hash (32 bytes)
90  * @param pScratchMem: Scratch Memory; At least a 492 byte buffer.
91  */
92 void
hmac_sha256_vector(void * priv,UINT8 * key,size_t key_len,size_t num_elem,UINT8 * addr[],size_t * len,UINT8 * mac,UINT8 * pScratchMem)93 hmac_sha256_vector(void *priv, UINT8 *key,
94 		   size_t key_len,
95 		   size_t num_elem,
96 		   UINT8 *addr[], size_t * len, UINT8 *mac, UINT8 *pScratchMem)
97 {
98 	phostsa_private psapriv = (phostsa_private)priv;
99 	hostsa_util_fns *util_fns = &psapriv->util_fns;
100 	size_t i;
101 	UINT8 *pKpad;		/* was UINT8 k_pad[64], padding - key XORd with ipad/opad */
102 	UINT8 *pTk;		/* was UINT8 tk[32] */
103 	UINT8 *pTmpBuf;
104 	UINT32 *ptrU32;
105 
106 	pKpad = pScratchMem;	/* kpad = 64 bytes */
107 	pTk = pKpad + 64;	/* tk = 32 bytes */
108 	pTmpBuf = pTk + 32;	/* offset into the scratch buf = +96 bytes */
109 
110 	/* if key is longer than 64 bytes reset it to key = SHA256(key) */
111 	if (key_len > 64) {
112 		/* pTmpBuf = At least 396 bytes */
113 		sha256_vector(priv, 1, &key, &key_len, pTk, pTmpBuf);
114 		key = pTk;
115 		key_len = 32;
116 	}
117 
118 	/* the HMAC_SHA256 transform looks like:
119 	 *
120 	 * SHA256(K XOR opad, SHA256(K XOR ipad, text))
121 	 *
122 	 * where K is an n byte key
123 	 * ipad is the byte 0x36 repeated 64 times
124 	 * opad is the byte 0x5c repeated 64 times
125 	 * and text is the data being protected
126 	 */
127 
128 	/* start out by storing key in ipad */
129 	memset(util_fns, pKpad, 0x00, 64);
130 	memcpy(util_fns, pKpad, key, key_len);
131 
132 	/* XOR key with ipad values */
133 	ptrU32 = (UINT32 *)pKpad;
134 	for (i = 16; i > 0; i--) {
135 		*ptrU32++ ^= 0x36363636;
136 	}
137 
138 	/* perform inner SHA256 */
139 	addr[0] = pKpad;
140 	len[0] = 64;
141 
142 	/* pTmpBuf = At least 396 bytes */
143 	sha256_vector((void *)priv, num_elem, addr, len, mac, pTmpBuf);
144 	memset(util_fns, pKpad, 0x00, 64);
145 	memcpy(util_fns, pKpad, key, key_len);
146 
147 	/* XOR key with opad values */
148 	ptrU32 = (UINT32 *)pKpad;
149 	for (i = 16; i > 0; i--) {
150 		*ptrU32++ ^= 0x5C5C5C5C;
151 	}
152 
153 	/* perform outer SHA256 */
154 	addr[0] = pKpad;
155 	len[0] = 64;
156 	addr[1] = mac;
157 	len[1] = SHA256_MAC_LEN;
158 
159 	/* pTmpBuf = At least 396 bytes */
160 	sha256_vector((void *)priv, 2, addr, len, mac, pTmpBuf);
161 }
162 
163 static int sha256_process(void *priv, struct sha256_state *md,
164 			  const UINT8 *in,
165 			  unsigned int inlen, UINT8 *pScratchMem);
166 
167 static int sha256_done(void *priv, struct sha256_state *md,
168 		       UINT8 *out, UINT8 *pScratchMem);
169 
170 /**
171  * @brief 	sha256_vector - SHA256 hash for data vector
172  * @param priv	pointer to previous element
173  * @param num_elem Number of elements in the data vector
174  * @param addr Pointers to the data areas
175  * @param len Lengths of the data blocks
176  * @param mac Buffer for the hash
177  * @param pScratchMem Scratch memory; At least (108 + 288) = 396 bytes  */
178 void
sha256_vector(void * priv,size_t num_elem,UINT8 * addr[],size_t * len,UINT8 * mac,UINT8 * pScratchMem)179 sha256_vector(void *priv, size_t num_elem,
180 	      UINT8 *addr[], size_t * len, UINT8 *mac, UINT8 *pScratchMem)
181 {
182 	UINT8 *pTmpBuf;
183 	size_t i;
184 	struct sha256_state *pCtx;
185 
186 	/*
187 	 ** sizeof(struct sha256_state)
188 	 **
189 	 **    UINT64 length                      =  8
190 	 **    UINT32 state[8], curlen; = (9 * 4) = 36
191 	 **    UINT8 buf[64];                     = 64
192 	 **                                       -----
193 	 **                                        108
194 	 */
195 	pCtx = (struct sha256_state *)pScratchMem;
196 	pTmpBuf = pScratchMem + sizeof(struct sha256_state);
197 
198 	sha256_init(pCtx);
199 
200 	for (i = 0; i < num_elem; i++) {
201 		/* pTmpBuf = At least 288 bytes of memory */
202 		sha256_process((void *)priv, pCtx, addr[i], len[i], pTmpBuf);
203 	}
204 	sha256_done((void *)priv, pCtx, mac, pTmpBuf);
205 }
206 
207 /* ===== start - public domain SHA256 implementation ===== */
208 
209 /* This is based on SHA256 implementation in LibTomCrypt that was released into
210  * public domain by Tom St Denis. */
211 
212 /* the K array */
213 static const unsigned int K[64] = {
214 	0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
215 	0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
216 	0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
217 	0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
218 	0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
219 	0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
220 	0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
221 	0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
222 	0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
223 	0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
224 	0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
225 	0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
226 	0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
227 };
228 
229 /* Various logical functions */
230 #define RORc(x, y)                                                      \
231     (((((unsigned int)(x) & 0xFFFFFFFFUL) >> (unsigned int)((y) & 31)) | \
232       ((unsigned int)(x) << (unsigned int)(32 - ((y) & 31)))) & 0xFFFFFFFFUL)
233 
234 #define Ch(x,y,z)       (z ^ (x & (y ^ z)))
235 #define Maj(x,y,z)      (((x | y) & z) | (x & y))
236 #define S(x, n)         RORc((x), (n))
237 #define R(x, n)         (((x)&0xFFFFFFFFUL)>>(n))
238 #define Sigma0(x)       (S(x, 2) ^ S(x, 13) ^ S(x, 22))
239 #define Sigma1(x)       (S(x, 6) ^ S(x, 11) ^ S(x, 25))
240 #define Gamma0(x)       (S(x, 7) ^ S(x, 18) ^ R(x, 3))
241 #define Gamma1(x)       (S(x, 17) ^ S(x, 19) ^ R(x, 10))
242 #ifndef MIN
243 #define MIN(x, y) (((x) < (y)) ? (x) : (y))
244 #endif
245 
246 /**
247  * sha256_compress - Compress 512-bits.
248  * @param md: Pointer to the element holding hash state.
249  * @param msgBuf: Pointer to the buffer containing the data to be hashed.
250  * @param pScratchMem: Scratch memory; At least 288 bytes of free memory *
251  *
252  */
253 int
sha256_compress(void * priv,struct sha256_state * md,UINT8 * msgBuf,UINT8 * pScratchMem)254 sha256_compress(void *priv, struct sha256_state *md,
255 		UINT8 *msgBuf, UINT8 *pScratchMem)
256 {
257 	phostsa_private psapriv = (phostsa_private)priv;
258 	hostsa_util_fns *util_fns = &psapriv->util_fns;
259 	UINT32 *pW;		/* was UINT32 W[64] */
260 	UINT32 *pS;		/* was UINT32 S[8]  */
261 	UINT32 t0;
262 	UINT32 t1;
263 	UINT32 t;
264 	UINT32 i;
265 	UINT32 *ptrU32;
266 
267 	/*   pW = (64 * 4) = 256
268 	 **   pS = (8 * 4)  =  32
269 	 **                 -----
270 	 **                   288
271 	 */
272 	ptrU32 = pW = (UINT32 *)pScratchMem;
273 	pS = pW + 64;
274 
275 	/* copy state into S */
276 	memcpy(util_fns, (UINT8 *)pS, (UINT8 *)md->state, 32);
277 
278 	/* copy the a message block of 512-bits into pW[0..15] */
279 	for (i = 16; i > 0; i--) {
280 		int a0, a1;
281 		a0 = *msgBuf++;
282 		a1 = *msgBuf++;
283 		a0 <<= 8;
284 		a0 |= a1;
285 		a1 = *msgBuf++;
286 		a0 <<= 8;
287 		a0 |= a1;
288 		a1 = *msgBuf++;
289 		a0 <<= 8;
290 		*ptrU32++ = a0 | a1;
291 	}
292 
293 	/* fill pW[16..63] */
294 	for (i = 48; i > 0; i--) {
295 		*ptrU32 =
296 			(Gamma1(ptrU32[-2]) + ptrU32[-7] + Gamma0(ptrU32[-15]) +
297 			 ptrU32[-16]);
298 		ptrU32++;
299 	}
300 
301 	/* Compress */
302 #define RND(a,b,c,d,e,f,g,h,i)                       \
303     t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + pW[i]; \
304     t1 = Sigma0(a) + Maj(a, b, c);                   \
305     d += t0;                                         \
306     h  = t0 + t1;
307 
308 	for (i = 0; i < 64; ++i) {
309 		RND(pS[0], pS[1], pS[2], pS[3], pS[4], pS[5], pS[6], pS[7], i);
310 		t = pS[7];
311 		pS[7] = pS[6];
312 		pS[6] = pS[5];
313 		pS[5] = pS[4];
314 		pS[4] = pS[3];
315 		pS[3] = pS[2];
316 		pS[2] = pS[1];
317 		pS[1] = pS[0];
318 		pS[0] = t;
319 	}
320 
321 	/* feedback */
322 	for (i = 0; i < 8; i++) {
323 		md->state[i] = md->state[i] + pS[i];
324 	}
325 	return 0;
326 }
327 
328 /* Initialize the hash state */
329 void
sha256_init(struct sha256_state * md)330 sha256_init(struct sha256_state *md)
331 {
332 	md->curlen = 0;
333 	md->length = 0;
334 	md->state[0] = 0x6A09E667UL;
335 	md->state[1] = 0xBB67AE85UL;
336 	md->state[2] = 0x3C6EF372UL;
337 	md->state[3] = 0xA54FF53AUL;
338 	md->state[4] = 0x510E527FUL;
339 	md->state[5] = 0x9B05688CUL;
340 	md->state[6] = 0x1F83D9ABUL;
341 	md->state[7] = 0x5BE0CD19UL;
342 }
343 
344 /**
345    Process a block of memory though the hash
346    @param md     The hash state
347    @param in     The data to hash
348    @param inlen  The length of the data (octets)
349    @param pScratchMem Temporary Memory Buf; At least 288 bytes.
350    @return CRYPT_OK if successful
351 */
352 static int
sha256_process(void * priv,struct sha256_state * md,const unsigned char * in,unsigned int inlen,UINT8 * pScratchMem)353 sha256_process(void *priv, struct sha256_state *md,
354 	       const unsigned char *in, unsigned int inlen, UINT8 *pScratchMem)
355 {
356 	phostsa_private psapriv = (phostsa_private)priv;
357 	hostsa_util_fns *util_fns = &psapriv->util_fns;
358 	unsigned int n;
359 #define block_size 64
360 
361 	if (md->curlen > sizeof(md->buf)) {
362 		return -1;
363 	}
364 
365 	while (inlen > 0) {
366 		if (md->curlen == 0 && inlen >= block_size) {
367 			/* pScratchMem = At least 288 bytes of memory */
368 			if (sha256_compress
369 			    ((void *)priv, md, (UINT8 *)in, pScratchMem) < 0) {
370 				return -1;
371 			}
372 			md->length += block_size * 8;
373 			in += block_size;
374 			inlen -= block_size;
375 		} else {
376 			n = MIN(inlen, (block_size - md->curlen));
377 			memcpy(util_fns, md->buf + md->curlen, in, n);
378 			md->curlen += n;
379 			in += n;
380 			inlen -= n;
381 			if (md->curlen == block_size) {
382 				/* pScratchMem = At least 288 bytes of memory */
383 				if (sha256_compress
384 				    ((void *)priv, md, md->buf,
385 				     pScratchMem) < 0) {
386 					return -1;
387 				}
388 				md->length += 8 * block_size;
389 				md->curlen = 0;
390 			}
391 		}
392 	}
393 
394 	return 0;
395 }
396 
397 /**
398    Terminate the hash to get the digest
399    @param md  The hash state
400    @param out [out] The destination of the hash (32 bytes)
401    @param pScratchMem [in] Scratch memory; At least 288 bytes
402    @return CRYPT_OK if successful
403 */
404 static int
sha256_done(void * priv,struct sha256_state * md,UINT8 * out,UINT8 * pScratchMem)405 sha256_done(void *priv, struct sha256_state *md, UINT8 *out, UINT8 *pScratchMem)
406 {
407 	int i;
408 	UINT32 *ptrU32;
409 	UINT32 tmpU32;
410 
411 	if (md->curlen >= sizeof(md->buf)) {
412 		return -1;
413 	}
414 
415 	/* increase the length of the message */
416 	md->length += md->curlen * 8;
417 
418 	/* append the '1' bit */
419 	md->buf[md->curlen++] = (unsigned char)0x80;
420 
421 	/* if the length is currently above 56 bytes we append zeros
422 	 * then compress.  Then we can fall back to padding zeros and length
423 	 * encoding like normal.
424 	 */
425 	if (md->curlen > 56) {
426 		while (md->curlen < 64) {
427 			md->buf[md->curlen++] = (unsigned char)0;
428 		}
429 		/* pScratchMem = At least 288 bytes of memory */
430 		sha256_compress((void *)priv, md, md->buf, pScratchMem);
431 		md->curlen = 0;
432 	}
433 
434 	/* pad upto 56 bytes of zeroes */
435 	while (md->curlen < 56) {
436 		md->buf[md->curlen++] = (unsigned char)0;
437 	}
438 
439 	/* store length */
440 	ptrU32 = (UINT32 *)&md->length;
441 	for (i = 0; i < 2; i++) {
442 		tmpU32 = *ptrU32++;
443 		WPA_PUT_BE32(md->buf + 60 - 4 * i, tmpU32);
444 	}
445 
446 	/* pScratchMem = At least 288 bytes of memory */
447 	sha256_compress((void *)priv, md, md->buf, pScratchMem);
448 
449 	ptrU32 = md->state;
450 	/* copy output */
451 	for (i = 8; i > 0; i--) {
452 		tmpU32 = *ptrU32++;
453 		WPA_PUT_BE32(out, tmpU32);
454 		out += sizeof(UINT32);
455 	}
456 	return 0;
457 }
458 
459 /* ===== end - public domain SHA256 implementation ===== */
460