18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SHA-256 hash implementation and interface functions
31f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Copyright (c) 2003-2011, Jouni Malinen <j@w1.fi>
48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license.
6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details.
78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h"
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h"
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "sha256.h"
131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include "sha256_i.h"
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto.h"
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * sha256_vector - SHA256 hash for data vector
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @num_elem: Number of elements in the data vector
208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: Pointers to the data areas
218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Lengths of the data blocks
228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @mac: Buffer for the hash
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 of failure
248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		  u8 *mac)
278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct sha256_state ctx;
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t i;
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	sha256_init(&ctx);
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < num_elem; i++)
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (sha256_process(&ctx, addr[i], len[i]))
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (sha256_done(&ctx, mac))
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* ===== start - public domain SHA256 implementation ===== */
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* This is based on SHA256 implementation in LibTomCrypt that was released into
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * public domain by Tom St Denis. */
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* the K array */
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const unsigned long K[64] = {
488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Various logical functions */
658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define RORc(x, y) \
668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt( ((((unsigned long) (x) & 0xFFFFFFFFUL) >> (unsigned long) ((y) & 31)) | \
678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   ((unsigned long) (x) << (unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL)
688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define Ch(x,y,z)       (z ^ (x & (y ^ z)))
698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define Maj(x,y,z)      (((x | y) & z) | (x & y))
708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define S(x, n)         RORc((x), (n))
718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define R(x, n)         (((x)&0xFFFFFFFFUL)>>(n))
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define Sigma0(x)       (S(x, 2) ^ S(x, 13) ^ S(x, 22))
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define Sigma1(x)       (S(x, 6) ^ S(x, 11) ^ S(x, 25))
748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define Gamma0(x)       (S(x, 7) ^ S(x, 18) ^ R(x, 3))
758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define Gamma1(x)       (S(x, 17) ^ S(x, 19) ^ R(x, 10))
768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef MIN
778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define MIN(x, y) (((x) < (y)) ? (x) : (y))
788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* compress 512-bits */
818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int sha256_compress(struct sha256_state *md, unsigned char *buf)
828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u32 S[8], W[64], t0, t1;
848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u32 t;
858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i;
868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* copy state into S */
888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < 8; i++) {
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		S[i] = md->state[i];
908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* copy the state into 512-bits into W[0..15] */
938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < 16; i++)
948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		W[i] = WPA_GET_BE32(buf + (4 * i));
958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* fill W[16..63] */
978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 16; i < 64; i++) {
988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) +
998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			W[i - 16];
1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Compress */
1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define RND(a,b,c,d,e,f,g,h,i)                          \
1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i];	\
1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	t1 = Sigma0(a) + Maj(a, b, c);			\
1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	d += t0;					\
1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	h  = t0 + t1;
1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < 64; ++i) {
1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i);
1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* feedback */
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < 8; i++) {
1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		md->state[i] = md->state[i] + S[i];
1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Initialize the hash state */
1241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid sha256_init(struct sha256_state *md)
1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	md->curlen = 0;
1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	md->length = 0;
1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	md->state[0] = 0x6A09E667UL;
1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	md->state[1] = 0xBB67AE85UL;
1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	md->state[2] = 0x3C6EF372UL;
1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	md->state[3] = 0xA54FF53AUL;
1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	md->state[4] = 0x510E527FUL;
1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	md->state[5] = 0x9B05688CUL;
1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	md->state[6] = 0x1F83D9ABUL;
1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	md->state[7] = 0x5BE0CD19UL;
1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   Process a block of memory though the hash
1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   @param md     The hash state
1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   @param in     The data to hash
1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   @param inlen  The length of the data (octets)
1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   @return CRYPT_OK if successful
1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt*/
1451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint sha256_process(struct sha256_state *md, const unsigned char *in,
1461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		   unsigned long inlen)
1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	unsigned long n;
1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (md->curlen >= sizeof(md->buf))
1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (inlen > 0) {
1541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (md->curlen == 0 && inlen >= SHA256_BLOCK_SIZE) {
1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (sha256_compress(md, (unsigned char *) in) < 0)
1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				return -1;
1571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			md->length += SHA256_BLOCK_SIZE * 8;
1581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			in += SHA256_BLOCK_SIZE;
1591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			inlen -= SHA256_BLOCK_SIZE;
1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else {
1611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			n = MIN(inlen, (SHA256_BLOCK_SIZE - md->curlen));
1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memcpy(md->buf + md->curlen, in, n);
1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			md->curlen += n;
1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			in += n;
1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			inlen -= n;
1661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (md->curlen == SHA256_BLOCK_SIZE) {
1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				if (sha256_compress(md, md->buf) < 0)
1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					return -1;
1691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				md->length += 8 * SHA256_BLOCK_SIZE;
1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				md->curlen = 0;
1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   Terminate the hash to get the digest
1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   @param md  The hash state
1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   @param out [out] The destination of the hash (32 bytes)
1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   @return CRYPT_OK if successful
1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt*/
1851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint sha256_done(struct sha256_state *md, unsigned char *out)
1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i;
1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (md->curlen >= sizeof(md->buf))
1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* increase the length of the message */
1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	md->length += md->curlen * 8;
1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* append the '1' bit */
1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	md->buf[md->curlen++] = (unsigned char) 0x80;
1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* if the length is currently above 56 bytes we append zeros
1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * then compress.  Then we can fall back to padding zeros and length
2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * encoding like normal.
2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (md->curlen > 56) {
2031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		while (md->curlen < SHA256_BLOCK_SIZE) {
2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			md->buf[md->curlen++] = (unsigned char) 0;
2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		sha256_compress(md, md->buf);
2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		md->curlen = 0;
2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	/* pad up to 56 bytes of zeroes */
2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (md->curlen < 56) {
2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		md->buf[md->curlen++] = (unsigned char) 0;
2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* store length */
2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	WPA_PUT_BE64(md->buf + 56, md->length);
2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	sha256_compress(md, md->buf);
2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* copy output */
2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < 8; i++)
2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		WPA_PUT_BE32(out + (4 * i), md->state[i]);
2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* ===== end - public domain SHA256 implementation ===== */
227