1526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/*
2526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * SHA1 hash implementation and interface functions
3526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
4526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *
5526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This program is free software; you can redistribute it and/or modify
6526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * it under the terms of the GNU General Public License version 2 as
7526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * published by the Free Software Foundation.
8526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *
9526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD
10526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * license.
11526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *
12526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * See README and COPYING for more details.
13526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */
14526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
15526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "includes.h"
16526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
17526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "common.h"
18b349ef9e9f3f5399bf96b3c1c663cb9e547f50a1Dmitry Shmidt#include "crypto/sha1.h"
19526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "md5.h"
20526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "crypto.h"
21526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
22526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
23526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/**
24526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * hmac_sha1_vector - HMAC-SHA1 over data vector (RFC 2104)
25526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @key: Key for HMAC operations
26526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @key_len: Length of the key in bytes
27526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @num_elem: Number of elements in the data vector
28526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @addr: Pointers to the data areas
29526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @len: Lengths of the data blocks
30526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @mac: Buffer for the hash (20 bytes)
31526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */
32526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
33526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		      const u8 *addr[], const size_t *len, u8 *mac)
34526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
35526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */
36526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	unsigned char tk[20];
37526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	const u8 *_addr[6];
38526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	size_t _len[6], i;
39526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
40526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (num_elem > 5) {
41526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		/*
42526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		 * Fixed limit on the number of fragments to avoid having to
43526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		 * allocate memory (which could fail).
44526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		 */
45526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		return;
46526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
47526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
48526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt        /* if key is longer than 64 bytes reset it to key = SHA1(key) */
49526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt        if (key_len > 64) {
50526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		sha1_vector(1, &key, &key_len, tk);
51526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		key = tk;
52526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		key_len = 20;
53526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt        }
54526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
55526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	/* the HMAC_SHA1 transform looks like:
56526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	 *
57526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	 * SHA1(K XOR opad, SHA1(K XOR ipad, text))
58526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	 *
59526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	 * where K is an n byte key
60526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	 * ipad is the byte 0x36 repeated 64 times
61526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	 * opad is the byte 0x5c repeated 64 times
62526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	 * and text is the data being protected */
63526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
64526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	/* start out by storing key in ipad */
65526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	os_memset(k_pad, 0, sizeof(k_pad));
66526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	os_memcpy(k_pad, key, key_len);
67526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	/* XOR key with ipad values */
68526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	for (i = 0; i < 64; i++)
69526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		k_pad[i] ^= 0x36;
70526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
71526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	/* perform inner SHA1 */
72526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	_addr[0] = k_pad;
73526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	_len[0] = 64;
74526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	for (i = 0; i < num_elem; i++) {
75526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		_addr[i + 1] = addr[i];
76526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		_len[i + 1] = len[i];
77526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
78526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	sha1_vector(1 + num_elem, _addr, _len, mac);
79526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
80526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	os_memset(k_pad, 0, sizeof(k_pad));
81526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	os_memcpy(k_pad, key, key_len);
82526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	/* XOR key with opad values */
83526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	for (i = 0; i < 64; i++)
84526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		k_pad[i] ^= 0x5c;
85526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
86526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	/* perform outer SHA1 */
87526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	_addr[0] = k_pad;
88526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	_len[0] = 64;
89526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	_addr[1] = mac;
90526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	_len[1] = SHA1_MAC_LEN;
91526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	sha1_vector(2, _addr, _len, mac);
92526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
93526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
94526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
95526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/**
96526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * hmac_sha1 - HMAC-SHA1 over data buffer (RFC 2104)
97526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @key: Key for HMAC operations
98526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @key_len: Length of the key in bytes
99526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @data: Pointers to the data area
100526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @data_len: Length of the data area
101526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @mac: Buffer for the hash (20 bytes)
102526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */
103526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
104526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	       u8 *mac)
105526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
106526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac);
107526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
108526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
109526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
110526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/**
111526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * sha1_prf - SHA1-based Pseudo-Random Function (PRF) (IEEE 802.11i, 8.5.1.1)
112526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @key: Key for PRF
113526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @key_len: Length of the key in bytes
114526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @label: A unique label for each purpose of the PRF
115526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @data: Extra data to bind into the key
116526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @data_len: Length of the data
117526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @buf: Buffer for the generated pseudo-random key
118526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @buf_len: Number of bytes of key to generate
119526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *
120526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This function is used to derive new, cryptographically separate keys from a
121526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * given key (e.g., PMK in IEEE 802.11i).
122526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */
123526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid sha1_prf(const u8 *key, size_t key_len, const char *label,
124526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	      const u8 *data, size_t data_len, u8 *buf, size_t buf_len)
125526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
126526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	u8 counter = 0;
127526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	size_t pos, plen;
128526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	u8 hash[SHA1_MAC_LEN];
129526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	size_t label_len = os_strlen(label) + 1;
130526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	const unsigned char *addr[3];
131526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	size_t len[3];
132526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
133526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	addr[0] = (u8 *) label;
134526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	len[0] = label_len;
135526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	addr[1] = data;
136526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	len[1] = data_len;
137526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	addr[2] = &counter;
138526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	len[2] = 1;
139526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
140526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	pos = 0;
141526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	while (pos < buf_len) {
142526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		plen = buf_len - pos;
143526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		if (plen >= SHA1_MAC_LEN) {
144526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			hmac_sha1_vector(key, key_len, 3, addr, len,
145526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt					 &buf[pos]);
146526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			pos += SHA1_MAC_LEN;
147526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		} else {
148526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			hmac_sha1_vector(key, key_len, 3, addr, len,
149526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt					 hash);
150526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			os_memcpy(&buf[pos], hash, plen);
151526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			break;
152526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		}
153526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		counter++;
154526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
155526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
156526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
157526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
158526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifndef CONFIG_NO_T_PRF
159526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/**
160526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * sha1_t_prf - EAP-FAST Pseudo-Random Function (T-PRF)
161526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @key: Key for PRF
162526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @key_len: Length of the key in bytes
163526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @label: A unique label for each purpose of the PRF
164526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @seed: Seed value to bind into the key
165526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @seed_len: Length of the seed
166526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @buf: Buffer for the generated pseudo-random key
167526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @buf_len: Number of bytes of key to generate
168526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *
169526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This function is used to derive new, cryptographically separate keys from a
170526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * given key for EAP-FAST. T-PRF is defined in RFC 4851, Section 5.5.
171526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */
172526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid sha1_t_prf(const u8 *key, size_t key_len, const char *label,
173526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		const u8 *seed, size_t seed_len, u8 *buf, size_t buf_len)
174526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
175526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	unsigned char counter = 0;
176526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	size_t pos, plen;
177526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	u8 hash[SHA1_MAC_LEN];
178526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	size_t label_len = os_strlen(label);
179526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	u8 output_len[2];
180526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	const unsigned char *addr[5];
181526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	size_t len[5];
182526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
183526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	addr[0] = hash;
184526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	len[0] = 0;
185526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	addr[1] = (unsigned char *) label;
186526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	len[1] = label_len + 1;
187526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	addr[2] = seed;
188526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	len[2] = seed_len;
189526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	addr[3] = output_len;
190526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	len[3] = 2;
191526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	addr[4] = &counter;
192526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	len[4] = 1;
193526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
194526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	output_len[0] = (buf_len >> 8) & 0xff;
195526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	output_len[1] = buf_len & 0xff;
196526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	pos = 0;
197526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	while (pos < buf_len) {
198526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		counter++;
199526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		plen = buf_len - pos;
200526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		hmac_sha1_vector(key, key_len, 5, addr, len, hash);
201526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		if (plen >= SHA1_MAC_LEN) {
202526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			os_memcpy(&buf[pos], hash, SHA1_MAC_LEN);
203526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			pos += SHA1_MAC_LEN;
204526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		} else {
205526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			os_memcpy(&buf[pos], hash, plen);
206526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			break;
207526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		}
208526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		len[0] = SHA1_MAC_LEN;
209526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
210526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
211526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* CONFIG_NO_T_PRF */
212526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
213526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
214526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifndef CONFIG_NO_TLS_PRF
215526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/**
216526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * tls_prf - Pseudo-Random Function for TLS (TLS-PRF, RFC 2246)
217526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @secret: Key for PRF
218526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @secret_len: Length of the key in bytes
219526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @label: A unique label for each purpose of the PRF
220526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @seed: Seed value to bind into the key
221526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @seed_len: Length of the seed
222526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @out: Buffer for the generated pseudo-random key
223526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @outlen: Number of bytes of key to generate
224526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: 0 on success, -1 on failure.
225526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *
226526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This function is used to derive new, cryptographically separate keys from a
227526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * given key in TLS. This PRF is defined in RFC 2246, Chapter 5.
228526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */
229526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint tls_prf(const u8 *secret, size_t secret_len, const char *label,
230526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	    const u8 *seed, size_t seed_len, u8 *out, size_t outlen)
231526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
232526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	size_t L_S1, L_S2, i;
233526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	const u8 *S1, *S2;
234526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	u8 A_MD5[MD5_MAC_LEN], A_SHA1[SHA1_MAC_LEN];
235526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	u8 P_MD5[MD5_MAC_LEN], P_SHA1[SHA1_MAC_LEN];
236526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	int MD5_pos, SHA1_pos;
237526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	const u8 *MD5_addr[3];
238526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	size_t MD5_len[3];
239526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	const unsigned char *SHA1_addr[3];
240526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	size_t SHA1_len[3];
241526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
242526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (secret_len & 1)
243526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		return -1;
244526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
245526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	MD5_addr[0] = A_MD5;
246526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	MD5_len[0] = MD5_MAC_LEN;
247526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	MD5_addr[1] = (unsigned char *) label;
248526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	MD5_len[1] = os_strlen(label);
249526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	MD5_addr[2] = seed;
250526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	MD5_len[2] = seed_len;
251526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
252526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	SHA1_addr[0] = A_SHA1;
253526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	SHA1_len[0] = SHA1_MAC_LEN;
254526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	SHA1_addr[1] = (unsigned char *) label;
255526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	SHA1_len[1] = os_strlen(label);
256526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	SHA1_addr[2] = seed;
257526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	SHA1_len[2] = seed_len;
258526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
259526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	/* RFC 2246, Chapter 5
260526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	 * A(0) = seed, A(i) = HMAC(secret, A(i-1))
261526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	 * P_hash = HMAC(secret, A(1) + seed) + HMAC(secret, A(2) + seed) + ..
262526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	 * PRF = P_MD5(S1, label + seed) XOR P_SHA-1(S2, label + seed)
263526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	 */
264526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
265526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	L_S1 = L_S2 = (secret_len + 1) / 2;
266526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	S1 = secret;
267526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	S2 = secret + L_S1;
268526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (secret_len & 1) {
269526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		/* The last byte of S1 will be shared with S2 */
270526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		S2--;
271526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
272526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
273526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	hmac_md5_vector(S1, L_S1, 2, &MD5_addr[1], &MD5_len[1], A_MD5);
274526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	hmac_sha1_vector(S2, L_S2, 2, &SHA1_addr[1], &SHA1_len[1], A_SHA1);
275526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
276526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	MD5_pos = MD5_MAC_LEN;
277526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	SHA1_pos = SHA1_MAC_LEN;
278526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	for (i = 0; i < outlen; i++) {
279526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		if (MD5_pos == MD5_MAC_LEN) {
280526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			hmac_md5_vector(S1, L_S1, 3, MD5_addr, MD5_len, P_MD5);
281526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			MD5_pos = 0;
282526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			hmac_md5(S1, L_S1, A_MD5, MD5_MAC_LEN, A_MD5);
283526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		}
284526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		if (SHA1_pos == SHA1_MAC_LEN) {
285526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			hmac_sha1_vector(S2, L_S2, 3, SHA1_addr, SHA1_len,
286526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt					 P_SHA1);
287526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			SHA1_pos = 0;
288526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			hmac_sha1(S2, L_S2, A_SHA1, SHA1_MAC_LEN, A_SHA1);
289526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		}
290526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
291526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		out[i] = P_MD5[MD5_pos] ^ P_SHA1[SHA1_pos];
292526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
293526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		MD5_pos++;
294526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		SHA1_pos++;
295526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
296526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
297526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	return 0;
298526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
299526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* CONFIG_NO_TLS_PRF */
300526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
301526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
302526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifndef CONFIG_NO_PBKDF2
303526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
304526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void pbkdf2_sha1_f(const char *passphrase, const char *ssid,
305526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			  size_t ssid_len, int iterations, unsigned int count,
306526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			  u8 *digest)
307526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
308526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	unsigned char tmp[SHA1_MAC_LEN], tmp2[SHA1_MAC_LEN];
309526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	int i, j;
310526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	unsigned char count_buf[4];
311526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	const u8 *addr[2];
312526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	size_t len[2];
313526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	size_t passphrase_len = os_strlen(passphrase);
314526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
315526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	addr[0] = (u8 *) ssid;
316526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	len[0] = ssid_len;
317526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	addr[1] = count_buf;
318526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	len[1] = 4;
319526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
320526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	/* F(P, S, c, i) = U1 xor U2 xor ... Uc
321526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	 * U1 = PRF(P, S || i)
322526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	 * U2 = PRF(P, U1)
323526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	 * Uc = PRF(P, Uc-1)
324526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	 */
325526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
326526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	count_buf[0] = (count >> 24) & 0xff;
327526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	count_buf[1] = (count >> 16) & 0xff;
328526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	count_buf[2] = (count >> 8) & 0xff;
329526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	count_buf[3] = count & 0xff;
330526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	hmac_sha1_vector((u8 *) passphrase, passphrase_len, 2, addr, len, tmp);
331526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	os_memcpy(digest, tmp, SHA1_MAC_LEN);
332526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
333526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	for (i = 1; i < iterations; i++) {
334526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		hmac_sha1((u8 *) passphrase, passphrase_len, tmp, SHA1_MAC_LEN,
335526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			  tmp2);
336526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		os_memcpy(tmp, tmp2, SHA1_MAC_LEN);
337526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		for (j = 0; j < SHA1_MAC_LEN; j++)
338526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			digest[j] ^= tmp2[j];
339526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
340526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
341526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
342526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
343526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/**
344526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * pbkdf2_sha1 - SHA1-based key derivation function (PBKDF2) for IEEE 802.11i
345526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @passphrase: ASCII passphrase
346526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @ssid: SSID
347526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @ssid_len: SSID length in bytes
348526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @iterations: Number of iterations to run
349526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @buf: Buffer for the generated key
350526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @buflen: Length of the buffer in bytes
351526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *
352526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This function is used to derive PSK for WPA-PSK. For this protocol,
353526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * iterations is set to 4096 and buflen to 32. This function is described in
354526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * IEEE Std 802.11-2004, Clause H.4. The main construction is from PKCS#5 v2.0.
355526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */
356526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len,
357526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		 int iterations, u8 *buf, size_t buflen)
358526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
359526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	unsigned int count = 0;
360526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	unsigned char *pos = buf;
361526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	size_t left = buflen, plen;
362526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	unsigned char digest[SHA1_MAC_LEN];
363526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
364526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	while (left > 0) {
365526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		count++;
366526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		pbkdf2_sha1_f(passphrase, ssid, ssid_len, iterations, count,
367526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			      digest);
368526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		plen = left > SHA1_MAC_LEN ? SHA1_MAC_LEN : left;
369526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		os_memcpy(pos, digest, plen);
370526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		pos += plen;
371526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		left -= plen;
372526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
373526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
374526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
375526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* CONFIG_NO_PBKDF2 */
376526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
377526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
378526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef INTERNAL_SHA1
379526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
380526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct SHA1Context {
381526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	u32 state[5];
382526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	u32 count[2];
383526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	unsigned char buffer[64];
384526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt};
385526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
386526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidttypedef struct SHA1Context SHA1_CTX;
387526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
388526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifndef CONFIG_CRYPTO_INTERNAL
389526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void SHA1Init(struct SHA1Context *context);
390526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void SHA1Update(struct SHA1Context *context, const void *data, u32 len);
391526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void SHA1Final(unsigned char digest[20], struct SHA1Context *context);
392526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* CONFIG_CRYPTO_INTERNAL */
393526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void SHA1Transform(u32 state[5], const unsigned char buffer[64]);
394526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
395526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
396526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/**
397526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * sha1_vector - SHA-1 hash for data vector
398526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @num_elem: Number of elements in the data vector
399526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @addr: Pointers to the data areas
400526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @len: Lengths of the data blocks
401526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @mac: Buffer for the hash
402526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */
403526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len,
404526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		 u8 *mac)
405526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
406526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	SHA1_CTX ctx;
407526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	size_t i;
408526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
409526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	SHA1Init(&ctx);
410526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	for (i = 0; i < num_elem; i++)
411526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		SHA1Update(&ctx, addr[i], len[i]);
412526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	SHA1Final(mac, &ctx);
413526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
414526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
415526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
416526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifndef CONFIG_NO_FIPS186_2_PRF
417526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint fips186_2_prf(const u8 *seed, size_t seed_len, u8 *x, size_t xlen)
418526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
419526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	u8 xkey[64];
420526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	u32 t[5], _t[5];
421526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	int i, j, m, k;
422526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	u8 *xpos = x;
423526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	u32 carry;
424526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
425526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (seed_len > sizeof(xkey))
426526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		seed_len = sizeof(xkey);
427526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
428526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	/* FIPS 186-2 + change notice 1 */
429526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
430526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	os_memcpy(xkey, seed, seed_len);
431526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	os_memset(xkey + seed_len, 0, 64 - seed_len);
432526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	t[0] = 0x67452301;
433526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	t[1] = 0xEFCDAB89;
434526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	t[2] = 0x98BADCFE;
435526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	t[3] = 0x10325476;
436526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	t[4] = 0xC3D2E1F0;
437526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
438526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	m = xlen / 40;
439526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	for (j = 0; j < m; j++) {
440526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		/* XSEED_j = 0 */
441526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		for (i = 0; i < 2; i++) {
442526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			/* XVAL = (XKEY + XSEED_j) mod 2^b */
443526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
444526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			/* w_i = G(t, XVAL) */
445526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			os_memcpy(_t, t, 20);
446526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			SHA1Transform(_t, xkey);
447526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			_t[0] = host_to_be32(_t[0]);
448526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			_t[1] = host_to_be32(_t[1]);
449526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			_t[2] = host_to_be32(_t[2]);
450526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			_t[3] = host_to_be32(_t[3]);
451526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			_t[4] = host_to_be32(_t[4]);
452526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			os_memcpy(xpos, _t, 20);
453526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
454526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			/* XKEY = (1 + XKEY + w_i) mod 2^b */
455526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			carry = 1;
456526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			for (k = 19; k >= 0; k--) {
457526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt				carry += xkey[k] + xpos[k];
458526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt				xkey[k] = carry & 0xff;
459526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt				carry >>= 8;
460526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			}
461526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
462526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			xpos += SHA1_MAC_LEN;
463526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		}
464526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		/* x_j = w_0|w_1 */
465526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
466526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
467526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	return 0;
468526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
469526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* CONFIG_NO_FIPS186_2_PRF */
470526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
471526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
472526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* ===== start - public domain SHA1 implementation ===== */
473526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
474526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/*
475526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSHA-1 in C
476526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtBy Steve Reid <sreid@sea-to-sky.net>
477526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt100% Public Domain
478526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
479526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt-----------------
480526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtModified 7/98
481526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtBy James H. Brown <jbrown@burgoyne.com>
482526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtStill 100% Public Domain
483526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
484526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtCorrected a problem which generated improper hash values on 16 bit machines
485526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtRoutine SHA1Update changed from
486526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int
487526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtlen)
488526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtto
489526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned
490526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtlong len)
491526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
492526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtThe 'len' parameter was declared an int which works fine on 32 bit machines.
493526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtHowever, on 16 bit machines an int is too small for the shifts being done
494526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtagainst
495526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtit.  This caused the hash function to generate incorrect values if len was
496526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtgreater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().
497526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
498526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSince the file IO in main() reads 16K at a time, any file 8K or larger would
499526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtbe guaranteed to generate the wrong hash (e.g. Test Vector #3, a million
500526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt"a"s).
501526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
502526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtI also changed the declaration of variables i & j in SHA1Update to
503526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtunsigned long from unsigned int for the same reason.
504526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
505526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtThese changes should make no difference to any 32 bit implementations since
506526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtan
507526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint and a long are the same size in those environments.
508526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
509526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt--
510526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtI also corrected a few compiler warnings generated by Borland C.
511526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt1. Added #include <process.h> for exit() prototype
512526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt2. Removed unused variable 'j' in SHA1Final
513526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt3. Changed exit(0) to return(0) at end of main.
514526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
515526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtALL changes I made can be located by searching for comments containing 'JHB'
516526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt-----------------
517526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtModified 8/98
518526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtBy Steve Reid <sreid@sea-to-sky.net>
519526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtStill 100% public domain
520526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
521526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt1- Removed #include <process.h> and used return() instead of exit()
522526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall)
523526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net
524526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
525526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt-----------------
526526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtModified 4/01
527526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtBy Saul Kravitz <Saul.Kravitz@celera.com>
528526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtStill 100% PD
529526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtModified to run on Compaq Alpha hardware.
530526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
531526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt-----------------
532526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtModified 4/01
533526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtBy Jouni Malinen <j@w1.fi>
534526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtMinor changes to match the coding style used in Dynamics.
535526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
536526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtModified September 24, 2004
537526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtBy Jouni Malinen <j@w1.fi>
538526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtFixed alignment issue in SHA1Transform when SHA1HANDSOFF is defined.
539526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
540526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt*/
541526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
542526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/*
543526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtTest Vectors (from FIPS PUB 180-1)
544526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt"abc"
545526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt  A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
546526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
547526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt  84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
548526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtA million repetitions of "a"
549526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt  34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
550526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt*/
551526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
552526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define SHA1HANDSOFF
553526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
554526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
555526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
556526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* blk0() and blk() perform the initial expand. */
557526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* I got the idea of expanding during the round function from SSLeay */
558526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifndef WORDS_BIGENDIAN
559526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define blk0(i) (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) | \
560526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	(rol(block->l[i], 8) & 0x00FF00FF))
561526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#else
562526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define blk0(i) block->l[i]
563526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif
564526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define blk(i) (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ \
565526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1))
566526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
567526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
568526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define R0(v,w,x,y,z,i) \
569526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \
570526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	w = rol(w, 30);
571526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define R1(v,w,x,y,z,i) \
572526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
573526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	w = rol(w, 30);
574526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define R2(v,w,x,y,z,i) \
575526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); w = rol(w, 30);
576526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define R3(v,w,x,y,z,i) \
577526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
578526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	w = rol(w, 30);
579526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define R4(v,w,x,y,z,i) \
580526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
581526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	w=rol(w, 30);
582526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
583526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
584526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef VERBOSE  /* SAK */
585526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid SHAPrintContext(SHA1_CTX *context, char *msg)
586526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
587526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	printf("%s (%d,%d) %x %x %x %x %x\n",
588526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	       msg,
589526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	       context->count[0], context->count[1],
590526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	       context->state[0],
591526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	       context->state[1],
592526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	       context->state[2],
593526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	       context->state[3],
594526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	       context->state[4]);
595526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
596526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif
597526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
598526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* Hash a single 512-bit block. This is the core of the algorithm. */
599526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
600526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void SHA1Transform(u32 state[5], const unsigned char buffer[64])
601526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
602526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	u32 a, b, c, d, e;
603526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	typedef union {
604526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		unsigned char c[64];
605526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		u32 l[16];
606526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	} CHAR64LONG16;
607526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	CHAR64LONG16* block;
608526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef SHA1HANDSOFF
609dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt	CHAR64LONG16 workspace;
610dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt	block = &workspace;
611526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	os_memcpy(block, buffer, 64);
612526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#else
613526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	block = (CHAR64LONG16 *) buffer;
614526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif
615526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	/* Copy context->state[] to working vars */
616526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	a = state[0];
617526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	b = state[1];
618526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	c = state[2];
619526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	d = state[3];
620526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	e = state[4];
621526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	/* 4 rounds of 20 operations each. Loop unrolled. */
622526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
623526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
624526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
625526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
626526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
627526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
628526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
629526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
630526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
631526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
632526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
633526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
634526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
635526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
636526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
637526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
638526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
639526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
640526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
641526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
642526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	/* Add the working vars back into context.state[] */
643526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	state[0] += a;
644526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	state[1] += b;
645526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	state[2] += c;
646526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	state[3] += d;
647526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	state[4] += e;
648526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	/* Wipe variables */
649526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	a = b = c = d = e = 0;
650526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef SHA1HANDSOFF
651526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	os_memset(block, 0, 64);
652526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif
653526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
654526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
655526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
656526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* SHA1Init - Initialize new context */
657526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
658526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid SHA1Init(SHA1_CTX* context)
659526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
660526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	/* SHA1 initialization constants */
661526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	context->state[0] = 0x67452301;
662526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	context->state[1] = 0xEFCDAB89;
663526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	context->state[2] = 0x98BADCFE;
664526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	context->state[3] = 0x10325476;
665526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	context->state[4] = 0xC3D2E1F0;
666526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	context->count[0] = context->count[1] = 0;
667526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
668526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
669526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
670526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* Run your data through this. */
671526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
672526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid SHA1Update(SHA1_CTX* context, const void *_data, u32 len)
673526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
674526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	u32 i, j;
675526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	const unsigned char *data = _data;
676526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
677526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef VERBOSE
678526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	SHAPrintContext(context, "before");
679526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif
680526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	j = (context->count[0] >> 3) & 63;
681526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if ((context->count[0] += len << 3) < (len << 3))
682526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		context->count[1]++;
683526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	context->count[1] += (len >> 29);
684526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if ((j + len) > 63) {
685526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		os_memcpy(&context->buffer[j], data, (i = 64-j));
686526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		SHA1Transform(context->state, context->buffer);
687526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		for ( ; i + 63 < len; i += 64) {
688526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			SHA1Transform(context->state, &data[i]);
689526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		}
690526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		j = 0;
691526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
692526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	else i = 0;
693526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	os_memcpy(&context->buffer[j], &data[i], len - i);
694526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef VERBOSE
695526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	SHAPrintContext(context, "after ");
696526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif
697526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
698526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
699526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
700526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* Add padding and return the message digest. */
701526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
702526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid SHA1Final(unsigned char digest[20], SHA1_CTX* context)
703526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
704526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	u32 i;
705526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	unsigned char finalcount[8];
706526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
707526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	for (i = 0; i < 8; i++) {
708526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		finalcount[i] = (unsigned char)
709526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			((context->count[(i >= 4 ? 0 : 1)] >>
710526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			  ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */
711526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
712526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	SHA1Update(context, (unsigned char *) "\200", 1);
713526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	while ((context->count[0] & 504) != 448) {
714526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		SHA1Update(context, (unsigned char *) "\0", 1);
715526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
716526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	SHA1Update(context, finalcount, 8);  /* Should cause a SHA1Transform()
717526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt					      */
718526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	for (i = 0; i < 20; i++) {
719526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		digest[i] = (unsigned char)
720526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) &
721526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			 255);
722526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
723526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	/* Wipe variables */
724526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	i = 0;
725526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	os_memset(context->buffer, 0, 64);
726526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	os_memset(context->state, 0, 20);
727526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	os_memset(context->count, 0, 8);
728526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	os_memset(finalcount, 0, 8);
729526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
730526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
731526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* ===== end - public domain SHA1 implementation ===== */
732526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
733526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* INTERNAL_SHA1 */
734