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