Merge branch 'vendor/LIBPCAP'
[dragonfly.git] / contrib / hostapd / src / crypto / sha256.c
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 = 1;
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 */