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
31d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt	if (TEST_FAIL())
32d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt		return -1;
33d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	sha256_init(&ctx);
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < num_elem; i++)
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (sha256_process(&ctx, addr[i], len[i]))
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (sha256_done(&ctx, mac))
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* ===== start - public domain SHA256 implementation ===== */
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* This is based on SHA256 implementation in LibTomCrypt that was released into
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * public domain by Tom St Denis. */
488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* the K array */
508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const unsigned long K[64] = {
518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Various logical functions */
688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define RORc(x, y) \
698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt( ((((unsigned long) (x) & 0xFFFFFFFFUL) >> (unsigned long) ((y) & 31)) | \
708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   ((unsigned long) (x) << (unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL)
718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define Ch(x,y,z)       (z ^ (x & (y ^ z)))
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define Maj(x,y,z)      (((x | y) & z) | (x & y))
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define S(x, n)         RORc((x), (n))
748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define R(x, n)         (((x)&0xFFFFFFFFUL)>>(n))
758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define Sigma0(x)       (S(x, 2) ^ S(x, 13) ^ S(x, 22))
768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define Sigma1(x)       (S(x, 6) ^ S(x, 11) ^ S(x, 25))
778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define Gamma0(x)       (S(x, 7) ^ S(x, 18) ^ R(x, 3))
788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define Gamma1(x)       (S(x, 17) ^ S(x, 19) ^ R(x, 10))
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef MIN
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define MIN(x, y) (((x) < (y)) ? (x) : (y))
818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif
828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* compress 512-bits */
848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int sha256_compress(struct sha256_state *md, unsigned char *buf)
858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u32 S[8], W[64], t0, t1;
878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u32 t;
888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i;
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* copy state into S */
918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < 8; i++) {
928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		S[i] = md->state[i];
938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* copy the state into 512-bits into W[0..15] */
968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < 16; i++)
978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		W[i] = WPA_GET_BE32(buf + (4 * i));
988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* fill W[16..63] */
1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 16; i < 64; i++) {
1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) +
1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			W[i - 16];
1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Compress */
1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define RND(a,b,c,d,e,f,g,h,i)                          \
1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i];	\
1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	t1 = Sigma0(a) + Maj(a, b, c);			\
1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	d += t0;					\
1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	h  = t0 + t1;
1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < 64; ++i) {
1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i);
1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* feedback */
1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < 8; i++) {
1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		md->state[i] = md->state[i] + S[i];
1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Initialize the hash state */
1271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid sha256_init(struct sha256_state *md)
1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	md->curlen = 0;
1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	md->length = 0;
1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	md->state[0] = 0x6A09E667UL;
1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	md->state[1] = 0xBB67AE85UL;
1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	md->state[2] = 0x3C6EF372UL;
1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	md->state[3] = 0xA54FF53AUL;
1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	md->state[4] = 0x510E527FUL;
1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	md->state[5] = 0x9B05688CUL;
1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	md->state[6] = 0x1F83D9ABUL;
1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	md->state[7] = 0x5BE0CD19UL;
1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   Process a block of memory though the hash
1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   @param md     The hash state
1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   @param in     The data to hash
1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   @param inlen  The length of the data (octets)
1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   @return CRYPT_OK if successful
1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt*/
1481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint sha256_process(struct sha256_state *md, const unsigned char *in,
1491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		   unsigned long inlen)
1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	unsigned long n;
1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (md->curlen >= sizeof(md->buf))
1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (inlen > 0) {
1571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (md->curlen == 0 && inlen >= SHA256_BLOCK_SIZE) {
1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (sha256_compress(md, (unsigned char *) in) < 0)
1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				return -1;
1601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			md->length += SHA256_BLOCK_SIZE * 8;
1611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			in += SHA256_BLOCK_SIZE;
1621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			inlen -= SHA256_BLOCK_SIZE;
1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else {
1641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			n = MIN(inlen, (SHA256_BLOCK_SIZE - md->curlen));
1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memcpy(md->buf + md->curlen, in, n);
1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			md->curlen += n;
1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			in += n;
1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			inlen -= n;
1691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (md->curlen == SHA256_BLOCK_SIZE) {
1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				if (sha256_compress(md, md->buf) < 0)
1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					return -1;
1721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				md->length += 8 * SHA256_BLOCK_SIZE;
1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				md->curlen = 0;
1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   Terminate the hash to get the digest
1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   @param md  The hash state
1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   @param out [out] The destination of the hash (32 bytes)
1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt   @return CRYPT_OK if successful
1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt*/
1881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint sha256_done(struct sha256_state *md, unsigned char *out)
1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i;
1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (md->curlen >= sizeof(md->buf))
1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* increase the length of the message */
1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	md->length += md->curlen * 8;
1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* append the '1' bit */
1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	md->buf[md->curlen++] = (unsigned char) 0x80;
2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* if the length is currently above 56 bytes we append zeros
2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * then compress.  Then we can fall back to padding zeros and length
2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * encoding like normal.
2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (md->curlen > 56) {
2061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		while (md->curlen < SHA256_BLOCK_SIZE) {
2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			md->buf[md->curlen++] = (unsigned char) 0;
2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		sha256_compress(md, md->buf);
2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		md->curlen = 0;
2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	/* pad up to 56 bytes of zeroes */
2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (md->curlen < 56) {
2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		md->buf[md->curlen++] = (unsigned char) 0;
2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* store length */
2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	WPA_PUT_BE64(md->buf + 56, md->length);
2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	sha256_compress(md, md->buf);
2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* copy output */
2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < 8; i++)
2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		WPA_PUT_BE32(out + (4 * i), md->state[i]);
2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* ===== end - public domain SHA256 implementation ===== */
230