xref: /freebsd/contrib/wpa/src/crypto/sha256.c (revision 39beb93c3f8bdbf72a61fda42300b5ebed7390c8)
1 /*
2  * SHA-256 hash implementation and interface functions
3  * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14 
15 #include "includes.h"
16 
17 #include "common.h"
18 #include "sha256.h"
19 #include "crypto.h"
20 
21 
22 /**
23  * hmac_sha256_vector - HMAC-SHA256 over data vector (RFC 2104)
24  * @key: Key for HMAC operations
25  * @key_len: Length of the key in bytes
26  * @num_elem: Number of elements in the data vector
27  * @addr: Pointers to the data areas
28  * @len: Lengths of the data blocks
29  * @mac: Buffer for the hash (32 bytes)
30  */
31 void hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,
32 			const u8 *addr[], const size_t *len, u8 *mac)
33 {
34 	unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */
35 	unsigned char tk[32];
36 	const u8 *_addr[6];
37 	size_t _len[6], i;
38 
39 	if (num_elem > 5) {
40 		/*
41 		 * Fixed limit on the number of fragments to avoid having to
42 		 * allocate memory (which could fail).
43 		 */
44 		return;
45 	}
46 
47         /* if key is longer than 64 bytes reset it to key = SHA256(key) */
48         if (key_len > 64) {
49 		sha256_vector(1, &key, &key_len, tk);
50 		key = tk;
51 		key_len = 32;
52         }
53 
54 	/* the HMAC_SHA256 transform looks like:
55 	 *
56 	 * SHA256(K XOR opad, SHA256(K XOR ipad, text))
57 	 *
58 	 * where K is an n byte key
59 	 * ipad is the byte 0x36 repeated 64 times
60 	 * opad is the byte 0x5c repeated 64 times
61 	 * and text is the data being protected */
62 
63 	/* start out by storing key in ipad */
64 	os_memset(k_pad, 0, sizeof(k_pad));
65 	os_memcpy(k_pad, key, key_len);
66 	/* XOR key with ipad values */
67 	for (i = 0; i < 64; i++)
68 		k_pad[i] ^= 0x36;
69 
70 	/* perform inner SHA256 */
71 	_addr[0] = k_pad;
72 	_len[0] = 64;
73 	for (i = 0; i < num_elem; i++) {
74 		_addr[i + 1] = addr[i];
75 		_len[i + 1] = len[i];
76 	}
77 	sha256_vector(1 + num_elem, _addr, _len, mac);
78 
79 	os_memset(k_pad, 0, sizeof(k_pad));
80 	os_memcpy(k_pad, key, key_len);
81 	/* XOR key with opad values */
82 	for (i = 0; i < 64; i++)
83 		k_pad[i] ^= 0x5c;
84 
85 	/* perform outer SHA256 */
86 	_addr[0] = k_pad;
87 	_len[0] = 64;
88 	_addr[1] = mac;
89 	_len[1] = SHA256_MAC_LEN;
90 	sha256_vector(2, _addr, _len, mac);
91 }
92 
93 
94 /**
95  * hmac_sha256 - HMAC-SHA256 over data buffer (RFC 2104)
96  * @key: Key for HMAC operations
97  * @key_len: Length of the key in bytes
98  * @data: Pointers to the data area
99  * @data_len: Length of the data area
100  * @mac: Buffer for the hash (20 bytes)
101  */
102 void hmac_sha256(const u8 *key, size_t key_len, const u8 *data,
103 		 size_t data_len, u8 *mac)
104 {
105 	hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac);
106 }
107 
108 
109 /**
110  * sha256_prf - SHA256-based Pseudo-Random Function (IEEE 802.11r, 8.5.1.5.2)
111  * @key: Key for PRF
112  * @key_len: Length of the key in bytes
113  * @label: A unique label for each purpose of the PRF
114  * @data: Extra data to bind into the key
115  * @data_len: Length of the data
116  * @buf: Buffer for the generated pseudo-random key
117  * @buf_len: Number of bytes of key to generate
118  *
119  * This function is used to derive new, cryptographically separate keys from a
120  * given key.
121  */
122 void sha256_prf(const u8 *key, size_t key_len, const char *label,
123 		const u8 *data, size_t data_len, u8 *buf, size_t buf_len)
124 {
125 	u16 counter = 0;
126 	size_t pos, plen;
127 	u8 hash[SHA256_MAC_LEN];
128 	const u8 *addr[4];
129 	size_t len[4];
130 	u8 counter_le[2], length_le[2];
131 
132 	addr[0] = counter_le;
133 	len[0] = 2;
134 	addr[1] = (u8 *) label;
135 	len[1] = os_strlen(label);
136 	addr[2] = data;
137 	len[2] = data_len;
138 	addr[3] = length_le;
139 	len[3] = sizeof(length_le);
140 
141 	WPA_PUT_LE16(length_le, buf_len * 8);
142 	pos = 0;
143 	while (pos < buf_len) {
144 		plen = buf_len - pos;
145 		WPA_PUT_LE16(counter_le, counter);
146 		if (plen >= SHA256_MAC_LEN) {
147 			hmac_sha256_vector(key, key_len, 4, addr, len,
148 					   &buf[pos]);
149 			pos += SHA256_MAC_LEN;
150 		} else {
151 			hmac_sha256_vector(key, key_len, 4, addr, len, hash);
152 			os_memcpy(&buf[pos], hash, plen);
153 			break;
154 		}
155 		counter++;
156 	}
157 }
158 
159 
160 #ifdef INTERNAL_SHA256
161 
162 struct sha256_state {
163 	u64 length;
164 	u32 state[8], curlen;
165 	u8 buf[64];
166 };
167 
168 static void sha256_init(struct sha256_state *md);
169 static int sha256_process(struct sha256_state *md, const unsigned char *in,
170 			  unsigned long inlen);
171 static int sha256_done(struct sha256_state *md, unsigned char *out);
172 
173 
174 /**
175  * sha256_vector - SHA256 hash for data vector
176  * @num_elem: Number of elements in the data vector
177  * @addr: Pointers to the data areas
178  * @len: Lengths of the data blocks
179  * @mac: Buffer for the hash
180  */
181 void sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
182 		 u8 *mac)
183 {
184 	struct sha256_state ctx;
185 	size_t i;
186 
187 	sha256_init(&ctx);
188 	for (i = 0; i < num_elem; i++)
189 		sha256_process(&ctx, addr[i], len[i]);
190 	sha256_done(&ctx, mac);
191 }
192 
193 
194 /* ===== start - public domain SHA256 implementation ===== */
195 
196 /* This is based on SHA256 implementation in LibTomCrypt that was released into
197  * public domain by Tom St Denis. */
198 
199 /* the K array */
200 static const unsigned long K[64] = {
201 	0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
202 	0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
203 	0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
204 	0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
205 	0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
206 	0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
207 	0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
208 	0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
209 	0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
210 	0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
211 	0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
212 	0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
213 	0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
214 };
215 
216 
217 /* Various logical functions */
218 #define RORc(x, y) \
219 ( ((((unsigned long) (x) & 0xFFFFFFFFUL) >> (unsigned long) ((y) & 31)) | \
220    ((unsigned long) (x) << (unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL)
221 #define Ch(x,y,z)       (z ^ (x & (y ^ z)))
222 #define Maj(x,y,z)      (((x | y) & z) | (x & y))
223 #define S(x, n)         RORc((x), (n))
224 #define R(x, n)         (((x)&0xFFFFFFFFUL)>>(n))
225 #define Sigma0(x)       (S(x, 2) ^ S(x, 13) ^ S(x, 22))
226 #define Sigma1(x)       (S(x, 6) ^ S(x, 11) ^ S(x, 25))
227 #define Gamma0(x)       (S(x, 7) ^ S(x, 18) ^ R(x, 3))
228 #define Gamma1(x)       (S(x, 17) ^ S(x, 19) ^ R(x, 10))
229 #ifndef MIN
230 #define MIN(x, y) (((x) < (y)) ? (x) : (y))
231 #endif
232 
233 /* compress 512-bits */
234 static int sha256_compress(struct sha256_state *md, unsigned char *buf)
235 {
236 	u32 S[8], W[64], t0, t1;
237 	u32 t;
238 	int i;
239 
240 	/* copy state into S */
241 	for (i = 0; i < 8; i++) {
242 		S[i] = md->state[i];
243 	}
244 
245 	/* copy the state into 512-bits into W[0..15] */
246 	for (i = 0; i < 16; i++)
247 		W[i] = WPA_GET_BE32(buf + (4 * i));
248 
249 	/* fill W[16..63] */
250 	for (i = 16; i < 64; i++) {
251 		W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) +
252 			W[i - 16];
253 	}
254 
255 	/* Compress */
256 #define RND(a,b,c,d,e,f,g,h,i)                          \
257 	t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i];	\
258 	t1 = Sigma0(a) + Maj(a, b, c);			\
259 	d += t0;					\
260 	h  = t0 + t1;
261 
262 	for (i = 0; i < 64; ++i) {
263 		RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i);
264 		t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
265 		S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
266 	}
267 
268 	/* feedback */
269 	for (i = 0; i < 8; i++) {
270 		md->state[i] = md->state[i] + S[i];
271 	}
272 	return 0;
273 }
274 
275 
276 /* Initialize the hash state */
277 static void sha256_init(struct sha256_state *md)
278 {
279 	md->curlen = 0;
280 	md->length = 0;
281 	md->state[0] = 0x6A09E667UL;
282 	md->state[1] = 0xBB67AE85UL;
283 	md->state[2] = 0x3C6EF372UL;
284 	md->state[3] = 0xA54FF53AUL;
285 	md->state[4] = 0x510E527FUL;
286 	md->state[5] = 0x9B05688CUL;
287 	md->state[6] = 0x1F83D9ABUL;
288 	md->state[7] = 0x5BE0CD19UL;
289 }
290 
291 /**
292    Process a block of memory though the hash
293    @param md     The hash state
294    @param in     The data to hash
295    @param inlen  The length of the data (octets)
296    @return CRYPT_OK if successful
297 */
298 static int sha256_process(struct sha256_state *md, const unsigned char *in,
299 			  unsigned long inlen)
300 {
301 	unsigned long n;
302 #define block_size 64
303 
304 	if (md->curlen > sizeof(md->buf))
305 		return -1;
306 
307 	while (inlen > 0) {
308 		if (md->curlen == 0 && inlen >= block_size) {
309 			if (sha256_compress(md, (unsigned char *) in) < 0)
310 				return -1;
311 			md->length += block_size * 8;
312 			in += block_size;
313 			inlen -= block_size;
314 		} else {
315 			n = MIN(inlen, (block_size - md->curlen));
316 			os_memcpy(md->buf + md->curlen, in, n);
317 			md->curlen += n;
318 			in += n;
319 			inlen -= n;
320 			if (md->curlen == block_size) {
321 				if (sha256_compress(md, md->buf) < 0)
322 					return -1;
323 				md->length += 8 * block_size;
324 				md->curlen = 0;
325 			}
326 		}
327 	}
328 
329 	return 0;
330 }
331 
332 
333 /**
334    Terminate the hash to get the digest
335    @param md  The hash state
336    @param out [out] The destination of the hash (32 bytes)
337    @return CRYPT_OK if successful
338 */
339 static int sha256_done(struct sha256_state *md, unsigned char *out)
340 {
341 	int i;
342 
343 	if (md->curlen >= sizeof(md->buf))
344 		return -1;
345 
346 	/* increase the length of the message */
347 	md->length += md->curlen * 8;
348 
349 	/* append the '1' bit */
350 	md->buf[md->curlen++] = (unsigned char) 0x80;
351 
352 	/* if the length is currently above 56 bytes we append zeros
353 	 * then compress.  Then we can fall back to padding zeros and length
354 	 * encoding like normal.
355 	 */
356 	if (md->curlen > 56) {
357 		while (md->curlen < 64) {
358 			md->buf[md->curlen++] = (unsigned char) 0;
359 		}
360 		sha256_compress(md, md->buf);
361 		md->curlen = 0;
362 	}
363 
364 	/* pad upto 56 bytes of zeroes */
365 	while (md->curlen < 56) {
366 		md->buf[md->curlen++] = (unsigned char) 0;
367 	}
368 
369 	/* store length */
370 	WPA_PUT_BE64(md->buf + 56, md->length);
371 	sha256_compress(md, md->buf);
372 
373 	/* copy output */
374 	for (i = 0; i < 8; i++)
375 		WPA_PUT_BE32(out + (4 * i), md->state[i]);
376 
377 	return 0;
378 }
379 
380 /* ===== end - public domain SHA256 implementation ===== */
381 
382 #endif /* INTERNAL_SHA256 */
383