1845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/*
2845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * SHA-256 hash implementation and interface functions
3845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi>
4845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *
5845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This program is free software; you can redistribute it and/or modify
6845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * it under the terms of the GNU General Public License version 2 as
7845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * published by the Free Software Foundation.
8845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *
9845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Alternatively, this software may be distributed under the terms of BSD
10845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * license.
11845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *
12845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * See README and COPYING for more details.
13845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */
14845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
15845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "includes.h"
16845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
17845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "common.h"
18845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "sha256.h"
19845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "crypto.h"
20845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
21845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
22845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/**
23845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * hmac_sha256_vector - HMAC-SHA256 over data vector (RFC 2104)
24845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @key: Key for HMAC operations
25845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @key_len: Length of the key in bytes
26845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @num_elem: Number of elements in the data vector
27845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @addr: Pointers to the data areas
28845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @len: Lengths of the data blocks
29845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @mac: Buffer for the hash (32 bytes)
30845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */
31845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,
32845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			const u8 *addr[], const size_t *len, u8 *mac)
33845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
34845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */
35845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	unsigned char tk[32];
36845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	const u8 *_addr[6];
37845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	size_t _len[6], i;
38845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
39845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (num_elem > 5) {
40845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		/*
41845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		 * Fixed limit on the number of fragments to avoid having to
42845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		 * allocate memory (which could fail).
43845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		 */
44845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return;
45845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
46845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
47845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project        /* if key is longer than 64 bytes reset it to key = SHA256(key) */
48845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project        if (key_len > 64) {
49845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		sha256_vector(1, &key, &key_len, tk);
50845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		key = tk;
51845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		key_len = 32;
52845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project        }
53845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
54845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	/* the HMAC_SHA256 transform looks like:
55845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	 *
56845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	 * SHA256(K XOR opad, SHA256(K XOR ipad, text))
57845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	 *
58845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	 * where K is an n byte key
59845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	 * ipad is the byte 0x36 repeated 64 times
60845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	 * opad is the byte 0x5c repeated 64 times
61845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	 * and text is the data being protected */
62845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
63845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	/* start out by storing key in ipad */
64845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	memset(k_pad, 0, sizeof(k_pad));
65845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	memcpy(k_pad, key, key_len);
66845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	/* XOR key with ipad values */
67845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	for (i = 0; i < 64; i++)
68845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		k_pad[i] ^= 0x36;
69845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
70845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	/* perform inner SHA256 */
71845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	_addr[0] = k_pad;
72845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	_len[0] = 64;
73845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	for (i = 0; i < num_elem; i++) {
74845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		_addr[i + 1] = addr[i];
75845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		_len[i + 1] = len[i];
76845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
77845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	sha256_vector(1 + num_elem, _addr, _len, mac);
78845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
79845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	memset(k_pad, 0, sizeof(k_pad));
80845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	memcpy(k_pad, key, key_len);
81845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	/* XOR key with opad values */
82845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	for (i = 0; i < 64; i++)
83845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		k_pad[i] ^= 0x5c;
84845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
85845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	/* perform outer SHA256 */
86845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	_addr[0] = k_pad;
87845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	_len[0] = 64;
88845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	_addr[1] = mac;
89845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	_len[1] = SHA256_MAC_LEN;
90845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	sha256_vector(2, _addr, _len, mac);
91845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
92845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
93845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
94845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/**
95845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * hmac_sha256 - HMAC-SHA256 over data buffer (RFC 2104)
96845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @key: Key for HMAC operations
97845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @key_len: Length of the key in bytes
98845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @data: Pointers to the data area
99845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @data_len: Length of the data area
100845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @mac: Buffer for the hash (20 bytes)
101845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */
102845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid hmac_sha256(const u8 *key, size_t key_len, const u8 *data,
103845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		 size_t data_len, u8 *mac)
104845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
105845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac);
106845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
107845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
108845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
109845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/**
110845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * sha256_prf - SHA256-based Pseudo-Random Function (IEEE 802.11r, 8.5A.3)
111845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @key: Key for PRF
112845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @key_len: Length of the key in bytes
113845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @label: A unique label for each purpose of the PRF
114845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @data: Extra data to bind into the key
115845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @data_len: Length of the data
116845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @buf: Buffer for the generated pseudo-random key
117845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @buf_len: Number of bytes of key to generate
118845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *
119845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This function is used to derive new, cryptographically separate keys from a
120845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * given key.
121845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */
122845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid sha256_prf(const u8 *key, size_t key_len, const char *label,
123845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		const u8 *data, size_t data_len, u8 *buf, size_t buf_len)
124845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
125845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	u16 counter = 0;
126845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	size_t pos, plen;
127845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	u8 hash[SHA256_MAC_LEN];
128845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	const u8 *addr[3];
129845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	size_t len[3];
130845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	u8 counter_le[2];
131845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
132845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	addr[0] = counter_le;
133845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	len[0] = 2;
134845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	addr[1] = (u8 *) label;
135845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	len[1] = strlen(label) + 1;
136845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	addr[2] = data;
137845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	len[2] = data_len;
138845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
139845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	pos = 0;
140845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	while (pos < buf_len) {
141845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		plen = buf_len - pos;
142845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		WPA_PUT_LE16(counter_le, counter);
143845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		if (plen >= SHA256_MAC_LEN) {
144845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			hmac_sha256_vector(key, key_len, 3, addr, len,
145845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project					   &buf[pos]);
146845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			pos += SHA256_MAC_LEN;
147845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		} else {
148845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			hmac_sha256_vector(key, key_len, 3, addr, len, hash);
149845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			memcpy(&buf[pos], hash, plen);
150845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			break;
151845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		}
152845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		counter++;
153845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
154845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
155845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
156845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
157845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#ifdef INTERNAL_SHA256
158845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
159845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstruct sha256_state {
160845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	u64 length;
161845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	u32 state[8], curlen;
162845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	u8 buf[64];
163845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project};
164845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
165845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void sha256_init(struct sha256_state *md);
166845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic int sha256_process(struct sha256_state *md, const unsigned char *in,
167845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			  unsigned long inlen);
168845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic int sha256_done(struct sha256_state *md, unsigned char *out);
169845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
170845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
171845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/**
172845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * sha256_vector - SHA256 hash for data vector
173845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @num_elem: Number of elements in the data vector
174845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @addr: Pointers to the data areas
175845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @len: Lengths of the data blocks
176845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * @mac: Buffer for the hash
177845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */
178845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
179845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		 u8 *mac)
180845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
181845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	struct sha256_state ctx;
182845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	size_t i;
183845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
184845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	sha256_init(&ctx);
185845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	for (i = 0; i < num_elem; i++)
186845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		sha256_process(&ctx, addr[i], len[i]);
187845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	sha256_done(&ctx, mac);
188845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
189845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
190845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
191845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* ===== start - public domain SHA256 implementation ===== */
192845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
193845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* This is based on SHA256 implementation in LibTomCrypt that was released into
194845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * public domain by Tom St Denis. */
195845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
196845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* the K array */
197845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic const unsigned long K[64] = {
198845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
199845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
200845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
201845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
202845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
203845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
204845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
205845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
206845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
207845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
208845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
209845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
210845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
211845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project};
212845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
213845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
214845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* Various logical functions */
215845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define RORc(x, y) \
216845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project( ((((unsigned long) (x) & 0xFFFFFFFFUL) >> (unsigned long) ((y) & 31)) | \
217845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project   ((unsigned long) (x) << (unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL)
218845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define Ch(x,y,z)       (z ^ (x & (y ^ z)))
219845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define Maj(x,y,z)      (((x | y) & z) | (x & y))
220845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define S(x, n)         RORc((x), (n))
221845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define R(x, n)         (((x)&0xFFFFFFFFUL)>>(n))
222845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define Sigma0(x)       (S(x, 2) ^ S(x, 13) ^ S(x, 22))
223845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define Sigma1(x)       (S(x, 6) ^ S(x, 11) ^ S(x, 25))
224845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define Gamma0(x)       (S(x, 7) ^ S(x, 18) ^ R(x, 3))
225845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define Gamma1(x)       (S(x, 17) ^ S(x, 19) ^ R(x, 10))
226845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#ifndef MIN
227845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define MIN(x, y) (((x) < (y)) ? (x) : (y))
228845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif
229845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
230845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* compress 512-bits */
231845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic int sha256_compress(struct sha256_state *md, unsigned char *buf)
232845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
233845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	u32 S[8], W[64], t0, t1;
234845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	u32 t;
235845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	int i;
236845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
237845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	/* copy state into S */
238845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	for (i = 0; i < 8; i++) {
239845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		S[i] = md->state[i];
240845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
241845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
242845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	/* copy the state into 512-bits into W[0..15] */
243845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	for (i = 0; i < 16; i++)
244845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		W[i] = WPA_GET_BE32(buf + (4 * i));
245845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
246845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	/* fill W[16..63] */
247845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	for (i = 16; i < 64; i++) {
248845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) +
249845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			W[i - 16];
250845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
251845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
252845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	/* Compress */
253845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define RND(a,b,c,d,e,f,g,h,i)                          \
254845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i];	\
255845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	t1 = Sigma0(a) + Maj(a, b, c);			\
256845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	d += t0;					\
257845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	h  = t0 + t1;
258845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
259845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	for (i = 0; i < 64; ++i) {
260845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i);
261845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
262845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
263845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
264845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
265845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	/* feedback */
266845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	for (i = 0; i < 8; i++) {
267845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		md->state[i] = md->state[i] + S[i];
268845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
269845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	return 0;
270845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
271845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
272845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
273845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* Initialize the hash state */
274845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void sha256_init(struct sha256_state *md)
275845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
276845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	md->curlen = 0;
277845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	md->length = 0;
278845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	md->state[0] = 0x6A09E667UL;
279845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	md->state[1] = 0xBB67AE85UL;
280845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	md->state[2] = 0x3C6EF372UL;
281845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	md->state[3] = 0xA54FF53AUL;
282845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	md->state[4] = 0x510E527FUL;
283845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	md->state[5] = 0x9B05688CUL;
284845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	md->state[6] = 0x1F83D9ABUL;
285845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	md->state[7] = 0x5BE0CD19UL;
286845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
287845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
288845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/**
289845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project   Process a block of memory though the hash
290845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project   @param md     The hash state
291845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project   @param in     The data to hash
292845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project   @param inlen  The length of the data (octets)
293845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project   @return CRYPT_OK if successful
294845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project*/
295845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic int sha256_process(struct sha256_state *md, const unsigned char *in,
296845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			  unsigned long inlen)
297845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
298845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	unsigned long n;
299845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define block_size 64
300845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
301845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (md->curlen > sizeof(md->buf))
302845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return -1;
303845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
304845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	while (inlen > 0) {
305845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		if (md->curlen == 0 && inlen >= block_size) {
306845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			if (sha256_compress(md, (unsigned char *) in) < 0)
307845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project				return -1;
308845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			md->length += block_size * 8;
309845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			in += block_size;
310845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			inlen -= block_size;
311845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		} else {
312845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			n = MIN(inlen, (block_size - md->curlen));
313845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			memcpy(md->buf + md->curlen, in, n);
314845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			md->curlen += n;
315845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			in += n;
316845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			inlen -= n;
317845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			if (md->curlen == block_size) {
318845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project				if (sha256_compress(md, md->buf) < 0)
319845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project					return -1;
320845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project				md->length += 8 * block_size;
321845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project				md->curlen = 0;
322845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			}
323845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		}
324845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
325845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
326845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	return 0;
327845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
328845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
329845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
330845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/**
331845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project   Terminate the hash to get the digest
332845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project   @param md  The hash state
333845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project   @param out [out] The destination of the hash (32 bytes)
334845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project   @return CRYPT_OK if successful
335845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project*/
336845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic int sha256_done(struct sha256_state *md, unsigned char *out)
337845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
338845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	int i;
339845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
340845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (md->curlen >= sizeof(md->buf))
341845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return -1;
342845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
343845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	/* increase the length of the message */
344845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	md->length += md->curlen * 8;
345845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
346845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	/* append the '1' bit */
347845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	md->buf[md->curlen++] = (unsigned char) 0x80;
348845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
349845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	/* if the length is currently above 56 bytes we append zeros
350845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	 * then compress.  Then we can fall back to padding zeros and length
351845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	 * encoding like normal.
352845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	 */
353845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (md->curlen > 56) {
354845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		while (md->curlen < 64) {
355845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			md->buf[md->curlen++] = (unsigned char) 0;
356845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		}
357845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		sha256_compress(md, md->buf);
358845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		md->curlen = 0;
359845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
360845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
361845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	/* pad upto 56 bytes of zeroes */
362845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	while (md->curlen < 56) {
363845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		md->buf[md->curlen++] = (unsigned char) 0;
364845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
365845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
366845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	/* store length */
367845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	WPA_PUT_BE64(md->buf + 56, md->length);
368845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	sha256_compress(md, md->buf);
369845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
370845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	/* copy output */
371845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	for (i = 0; i < 8; i++)
372845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		WPA_PUT_BE32(out + (4 * i), md->state[i]);
373845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
374845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	return 0;
375845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
376845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
377845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* ===== end - public domain SHA256 implementation ===== */
378845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
379845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif /* INTERNAL_SHA256 */
380