$search
00001 /* 00002 * SHA-256 hash implementation and interface functions 00003 * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation. 00008 * 00009 * Alternatively, this software may be distributed under the terms of BSD 00010 * license. 00011 * 00012 * See README and COPYING for more details. 00013 */ 00014 00015 #include "includes.h" 00016 00017 #include "common.h" 00018 #include "sha256.h" 00019 #include "crypto.h" 00020 00021 struct sha256_state { 00022 u64 length; 00023 u32 state[8], curlen; 00024 u8 buf[64]; 00025 }; 00026 00027 static void sha256_init(struct sha256_state *md); 00028 static int sha256_process(struct sha256_state *md, const unsigned char *in, 00029 unsigned long inlen); 00030 static int sha256_done(struct sha256_state *md, unsigned char *out); 00031 00032 00041 int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, 00042 u8 *mac) 00043 { 00044 struct sha256_state ctx; 00045 size_t i; 00046 00047 sha256_init(&ctx); 00048 for (i = 0; i < num_elem; i++) 00049 if (sha256_process(&ctx, addr[i], len[i])) 00050 return -1; 00051 if (sha256_done(&ctx, mac)) 00052 return -1; 00053 return 0; 00054 } 00055 00056 00057 /* ===== start - public domain SHA256 implementation ===== */ 00058 00059 /* This is based on SHA256 implementation in LibTomCrypt that was released into 00060 * public domain by Tom St Denis. */ 00061 00062 /* the K array */ 00063 static const unsigned long K[64] = { 00064 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, 00065 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, 00066 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 00067 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, 00068 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, 00069 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, 00070 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 00071 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, 00072 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, 00073 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, 00074 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 00075 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, 00076 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL 00077 }; 00078 00079 00080 /* Various logical functions */ 00081 #define RORc(x, y) \ 00082 ( ((((unsigned long) (x) & 0xFFFFFFFFUL) >> (unsigned long) ((y) & 31)) | \ 00083 ((unsigned long) (x) << (unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL) 00084 #define Ch(x,y,z) (z ^ (x & (y ^ z))) 00085 #define Maj(x,y,z) (((x | y) & z) | (x & y)) 00086 #define S(x, n) RORc((x), (n)) 00087 #define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) 00088 #define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) 00089 #define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) 00090 #define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) 00091 #define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) 00092 #ifndef MIN 00093 #define MIN(x, y) (((x) < (y)) ? (x) : (y)) 00094 #endif 00095 00096 /* compress 512-bits */ 00097 static int sha256_compress(struct sha256_state *md, unsigned char *buf) 00098 { 00099 u32 S[8], W[64], t0, t1; 00100 u32 t; 00101 int i; 00102 00103 /* copy state into S */ 00104 for (i = 0; i < 8; i++) { 00105 S[i] = md->state[i]; 00106 } 00107 00108 /* copy the state into 512-bits into W[0..15] */ 00109 for (i = 0; i < 16; i++) 00110 W[i] = WPA_GET_BE32(buf + (4 * i)); 00111 00112 /* fill W[16..63] */ 00113 for (i = 16; i < 64; i++) { 00114 W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + 00115 W[i - 16]; 00116 } 00117 00118 /* Compress */ 00119 #define RND(a,b,c,d,e,f,g,h,i) \ 00120 t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ 00121 t1 = Sigma0(a) + Maj(a, b, c); \ 00122 d += t0; \ 00123 h = t0 + t1; 00124 00125 for (i = 0; i < 64; ++i) { 00126 RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i); 00127 t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4]; 00128 S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t; 00129 } 00130 00131 /* feedback */ 00132 for (i = 0; i < 8; i++) { 00133 md->state[i] = md->state[i] + S[i]; 00134 } 00135 return 0; 00136 } 00137 00138 00139 /* Initialize the hash state */ 00140 static void sha256_init(struct sha256_state *md) 00141 { 00142 md->curlen = 0; 00143 md->length = 0; 00144 md->state[0] = 0x6A09E667UL; 00145 md->state[1] = 0xBB67AE85UL; 00146 md->state[2] = 0x3C6EF372UL; 00147 md->state[3] = 0xA54FF53AUL; 00148 md->state[4] = 0x510E527FUL; 00149 md->state[5] = 0x9B05688CUL; 00150 md->state[6] = 0x1F83D9ABUL; 00151 md->state[7] = 0x5BE0CD19UL; 00152 } 00153 00161 static int sha256_process(struct sha256_state *md, const unsigned char *in, 00162 unsigned long inlen) 00163 { 00164 unsigned long n; 00165 #define block_size 64 00166 00167 if (md->curlen > sizeof(md->buf)) 00168 return -1; 00169 00170 while (inlen > 0) { 00171 if (md->curlen == 0 && inlen >= block_size) { 00172 if (sha256_compress(md, (unsigned char *) in) < 0) 00173 return -1; 00174 md->length += block_size * 8; 00175 in += block_size; 00176 inlen -= block_size; 00177 } else { 00178 n = MIN(inlen, (block_size - md->curlen)); 00179 os_memcpy(md->buf + md->curlen, in, n); 00180 md->curlen += n; 00181 in += n; 00182 inlen -= n; 00183 if (md->curlen == block_size) { 00184 if (sha256_compress(md, md->buf) < 0) 00185 return -1; 00186 md->length += 8 * block_size; 00187 md->curlen = 0; 00188 } 00189 } 00190 } 00191 00192 return 0; 00193 } 00194 00195 00202 static int sha256_done(struct sha256_state *md, unsigned char *out) 00203 { 00204 int i; 00205 00206 if (md->curlen >= sizeof(md->buf)) 00207 return -1; 00208 00209 /* increase the length of the message */ 00210 md->length += md->curlen * 8; 00211 00212 /* append the '1' bit */ 00213 md->buf[md->curlen++] = (unsigned char) 0x80; 00214 00215 /* if the length is currently above 56 bytes we append zeros 00216 * then compress. Then we can fall back to padding zeros and length 00217 * encoding like normal. 00218 */ 00219 if (md->curlen > 56) { 00220 while (md->curlen < 64) { 00221 md->buf[md->curlen++] = (unsigned char) 0; 00222 } 00223 sha256_compress(md, md->buf); 00224 md->curlen = 0; 00225 } 00226 00227 /* pad upto 56 bytes of zeroes */ 00228 while (md->curlen < 56) { 00229 md->buf[md->curlen++] = (unsigned char) 0; 00230 } 00231 00232 /* store length */ 00233 WPA_PUT_BE64(md->buf + 56, md->length); 00234 sha256_compress(md, md->buf); 00235 00236 /* copy output */ 00237 for (i = 0; i < 8; i++) 00238 WPA_PUT_BE32(out + (4 * i), md->state[i]); 00239 00240 return 0; 00241 } 00242 00243 /* ===== end - public domain SHA256 implementation ===== */