Home | History | Annotate | Download | only in wpa_supplicant
      1 /*
      2  * SHA-256 hash implementation and interface functions
      3  * Copyright (c) 2003-2006, Jouni Malinen <j (at) 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 	memset(k_pad, 0, sizeof(k_pad));
     65 	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 	memset(k_pad, 0, sizeof(k_pad));
     80 	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.5A.3)
    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[3];
    129 	size_t len[3];
    130 	u8 counter_le[2];
    131 
    132 	addr[0] = counter_le;
    133 	len[0] = 2;
    134 	addr[1] = (u8 *) label;
    135 	len[1] = strlen(label) + 1;
    136 	addr[2] = data;
    137 	len[2] = data_len;
    138 
    139 	pos = 0;
    140 	while (pos < buf_len) {
    141 		plen = buf_len - pos;
    142 		WPA_PUT_LE16(counter_le, counter);
    143 		if (plen >= SHA256_MAC_LEN) {
    144 			hmac_sha256_vector(key, key_len, 3, addr, len,
    145 					   &buf[pos]);
    146 			pos += SHA256_MAC_LEN;
    147 		} else {
    148 			hmac_sha256_vector(key, key_len, 3, addr, len, hash);
    149 			memcpy(&buf[pos], hash, plen);
    150 			break;
    151 		}
    152 		counter++;
    153 	}
    154 }
    155 
    156 
    157 #ifdef INTERNAL_SHA256
    158 
    159 struct sha256_state {
    160 	u64 length;
    161 	u32 state[8], curlen;
    162 	u8 buf[64];
    163 };
    164 
    165 static void sha256_init(struct sha256_state *md);
    166 static int sha256_process(struct sha256_state *md, const unsigned char *in,
    167 			  unsigned long inlen);
    168 static int sha256_done(struct sha256_state *md, unsigned char *out);
    169 
    170 
    171 /**
    172  * sha256_vector - SHA256 hash for data vector
    173  * @num_elem: Number of elements in the data vector
    174  * @addr: Pointers to the data areas
    175  * @len: Lengths of the data blocks
    176  * @mac: Buffer for the hash
    177  */
    178 void sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
    179 		 u8 *mac)
    180 {
    181 	struct sha256_state ctx;
    182 	size_t i;
    183 
    184 	sha256_init(&ctx);
    185 	for (i = 0; i < num_elem; i++)
    186 		sha256_process(&ctx, addr[i], len[i]);
    187 	sha256_done(&ctx, mac);
    188 }
    189 
    190 
    191 /* ===== start - public domain SHA256 implementation ===== */
    192 
    193 /* This is based on SHA256 implementation in LibTomCrypt that was released into
    194  * public domain by Tom St Denis. */
    195 
    196 /* the K array */
    197 static const unsigned long K[64] = {
    198 	0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
    199 	0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
    200 	0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
    201 	0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
    202 	0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
    203 	0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
    204 	0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
    205 	0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
    206 	0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
    207 	0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
    208 	0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
    209 	0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
    210 	0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
    211 };
    212 
    213 
    214 /* Various logical functions */
    215 #define RORc(x, y) \
    216 ( ((((unsigned long) (x) & 0xFFFFFFFFUL) >> (unsigned long) ((y) & 31)) | \
    217    ((unsigned long) (x) << (unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL)
    218 #define Ch(x,y,z)       (z ^ (x & (y ^ z)))
    219 #define Maj(x,y,z)      (((x | y) & z) | (x & y))
    220 #define S(x, n)         RORc((x), (n))
    221 #define R(x, n)         (((x)&0xFFFFFFFFUL)>>(n))
    222 #define Sigma0(x)       (S(x, 2) ^ S(x, 13) ^ S(x, 22))
    223 #define Sigma1(x)       (S(x, 6) ^ S(x, 11) ^ S(x, 25))
    224 #define Gamma0(x)       (S(x, 7) ^ S(x, 18) ^ R(x, 3))
    225 #define Gamma1(x)       (S(x, 17) ^ S(x, 19) ^ R(x, 10))
    226 #ifndef MIN
    227 #define MIN(x, y) (((x) < (y)) ? (x) : (y))
    228 #endif
    229 
    230 /* compress 512-bits */
    231 static int sha256_compress(struct sha256_state *md, unsigned char *buf)
    232 {
    233 	u32 S[8], W[64], t0, t1;
    234 	u32 t;
    235 	int i;
    236 
    237 	/* copy state into S */
    238 	for (i = 0; i < 8; i++) {
    239 		S[i] = md->state[i];
    240 	}
    241 
    242 	/* copy the state into 512-bits into W[0..15] */
    243 	for (i = 0; i < 16; i++)
    244 		W[i] = WPA_GET_BE32(buf + (4 * i));
    245 
    246 	/* fill W[16..63] */
    247 	for (i = 16; i < 64; i++) {
    248 		W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) +
    249 			W[i - 16];
    250 	}
    251 
    252 	/* Compress */
    253 #define RND(a,b,c,d,e,f,g,h,i)                          \
    254 	t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i];	\
    255 	t1 = Sigma0(a) + Maj(a, b, c);			\
    256 	d += t0;					\
    257 	h  = t0 + t1;
    258 
    259 	for (i = 0; i < 64; ++i) {
    260 		RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i);
    261 		t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
    262 		S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
    263 	}
    264 
    265 	/* feedback */
    266 	for (i = 0; i < 8; i++) {
    267 		md->state[i] = md->state[i] + S[i];
    268 	}
    269 	return 0;
    270 }
    271 
    272 
    273 /* Initialize the hash state */
    274 static void sha256_init(struct sha256_state *md)
    275 {
    276 	md->curlen = 0;
    277 	md->length = 0;
    278 	md->state[0] = 0x6A09E667UL;
    279 	md->state[1] = 0xBB67AE85UL;
    280 	md->state[2] = 0x3C6EF372UL;
    281 	md->state[3] = 0xA54FF53AUL;
    282 	md->state[4] = 0x510E527FUL;
    283 	md->state[5] = 0x9B05688CUL;
    284 	md->state[6] = 0x1F83D9ABUL;
    285 	md->state[7] = 0x5BE0CD19UL;
    286 }
    287 
    288 /**
    289    Process a block of memory though the hash
    290    @param md     The hash state
    291    @param in     The data to hash
    292    @param inlen  The length of the data (octets)
    293    @return CRYPT_OK if successful
    294 */
    295 static int sha256_process(struct sha256_state *md, const unsigned char *in,
    296 			  unsigned long inlen)
    297 {
    298 	unsigned long n;
    299 #define block_size 64
    300 
    301 	if (md->curlen > sizeof(md->buf))
    302 		return -1;
    303 
    304 	while (inlen > 0) {
    305 		if (md->curlen == 0 && inlen >= block_size) {
    306 			if (sha256_compress(md, (unsigned char *) in) < 0)
    307 				return -1;
    308 			md->length += block_size * 8;
    309 			in += block_size;
    310 			inlen -= block_size;
    311 		} else {
    312 			n = MIN(inlen, (block_size - md->curlen));
    313 			memcpy(md->buf + md->curlen, in, n);
    314 			md->curlen += n;
    315 			in += n;
    316 			inlen -= n;
    317 			if (md->curlen == block_size) {
    318 				if (sha256_compress(md, md->buf) < 0)
    319 					return -1;
    320 				md->length += 8 * block_size;
    321 				md->curlen = 0;
    322 			}
    323 		}
    324 	}
    325 
    326 	return 0;
    327 }
    328 
    329 
    330 /**
    331    Terminate the hash to get the digest
    332    @param md  The hash state
    333    @param out [out] The destination of the hash (32 bytes)
    334    @return CRYPT_OK if successful
    335 */
    336 static int sha256_done(struct sha256_state *md, unsigned char *out)
    337 {
    338 	int i;
    339 
    340 	if (md->curlen >= sizeof(md->buf))
    341 		return -1;
    342 
    343 	/* increase the length of the message */
    344 	md->length += md->curlen * 8;
    345 
    346 	/* append the '1' bit */
    347 	md->buf[md->curlen++] = (unsigned char) 0x80;
    348 
    349 	/* if the length is currently above 56 bytes we append zeros
    350 	 * then compress.  Then we can fall back to padding zeros and length
    351 	 * encoding like normal.
    352 	 */
    353 	if (md->curlen > 56) {
    354 		while (md->curlen < 64) {
    355 			md->buf[md->curlen++] = (unsigned char) 0;
    356 		}
    357 		sha256_compress(md, md->buf);
    358 		md->curlen = 0;
    359 	}
    360 
    361 	/* pad upto 56 bytes of zeroes */
    362 	while (md->curlen < 56) {
    363 		md->buf[md->curlen++] = (unsigned char) 0;
    364 	}
    365 
    366 	/* store length */
    367 	WPA_PUT_BE64(md->buf + 56, md->length);
    368 	sha256_compress(md, md->buf);
    369 
    370 	/* copy output */
    371 	for (i = 0; i < 8; i++)
    372 		WPA_PUT_BE32(out + (4 * i), md->state[i]);
    373 
    374 	return 0;
    375 }
    376 
    377 /* ===== end - public domain SHA256 implementation ===== */
    378 
    379 #endif /* INTERNAL_SHA256 */
    380