sha256-internal.c
Go to the documentation of this file.
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 ===== */


wpa_supplicant_node
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Jan 2 2014 11:25:14