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