sha256-internal.c

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

Generated on Sat Nov 21 23:16:50 2009 for hostapd by  doxygen 1.6.1