~ubuntu-branches/ubuntu/saucy/wpasupplicant/saucy

« back to all changes in this revision

Viewing changes to src/crypto/sha256.c

  • Committer: Bazaar Package Importer
  • Author(s): Mathieu Trudel-Lapierre
  • Date: 2010-11-22 09:43:43 UTC
  • mfrom: (1.1.16 upstream)
  • Revision ID: james.westby@ubuntu.com-20101122094343-qgsxaojvmswfri77
Tags: 0.7.3-0ubuntu1
* Get wpasupplicant 0.7.3 from Debian's SVN. Leaving 0.7.3-1 as unreleased
  for now.
* Build-Depend on debhelper 8, since the packaging from Debian uses compat 8.

Show diffs side-by-side

added added

removed removed

Lines of Context:
155
155
                counter++;
156
156
        }
157
157
}
158
 
 
159
 
 
160
 
#ifdef INTERNAL_SHA256
161
 
 
162
 
struct sha256_state {
163
 
        u64 length;
164
 
        u32 state[8], curlen;
165
 
        u8 buf[64];
166
 
};
167
 
 
168
 
static void sha256_init(struct sha256_state *md);
169
 
static int sha256_process(struct sha256_state *md, const unsigned char *in,
170
 
                          unsigned long inlen);
171
 
static int sha256_done(struct sha256_state *md, unsigned char *out);
172
 
 
173
 
 
174
 
/**
175
 
 * sha256_vector - SHA256 hash for data vector
176
 
 * @num_elem: Number of elements in the data vector
177
 
 * @addr: Pointers to the data areas
178
 
 * @len: Lengths of the data blocks
179
 
 * @mac: Buffer for the hash
180
 
 */
181
 
void sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
182
 
                 u8 *mac)
183
 
{
184
 
        struct sha256_state ctx;
185
 
        size_t i;
186
 
 
187
 
        sha256_init(&ctx);
188
 
        for (i = 0; i < num_elem; i++)
189
 
                sha256_process(&ctx, addr[i], len[i]);
190
 
        sha256_done(&ctx, mac);
191
 
}
192
 
 
193
 
 
194
 
/* ===== start - public domain SHA256 implementation ===== */
195
 
 
196
 
/* This is based on SHA256 implementation in LibTomCrypt that was released into
197
 
 * public domain by Tom St Denis. */
198
 
 
199
 
/* the K array */
200
 
static const unsigned long K[64] = {
201
 
        0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
202
 
        0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
203
 
        0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
204
 
        0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
205
 
        0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
206
 
        0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
207
 
        0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
208
 
        0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
209
 
        0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
210
 
        0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
211
 
        0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
212
 
        0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
213
 
        0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
214
 
};
215
 
 
216
 
 
217
 
/* Various logical functions */
218
 
#define RORc(x, y) \
219
 
( ((((unsigned long) (x) & 0xFFFFFFFFUL) >> (unsigned long) ((y) & 31)) | \
220
 
   ((unsigned long) (x) << (unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL)
221
 
#define Ch(x,y,z)       (z ^ (x & (y ^ z)))
222
 
#define Maj(x,y,z)      (((x | y) & z) | (x & y)) 
223
 
#define S(x, n)         RORc((x), (n))
224
 
#define R(x, n)         (((x)&0xFFFFFFFFUL)>>(n))
225
 
#define Sigma0(x)       (S(x, 2) ^ S(x, 13) ^ S(x, 22))
226
 
#define Sigma1(x)       (S(x, 6) ^ S(x, 11) ^ S(x, 25))
227
 
#define Gamma0(x)       (S(x, 7) ^ S(x, 18) ^ R(x, 3))
228
 
#define Gamma1(x)       (S(x, 17) ^ S(x, 19) ^ R(x, 10))
229
 
#ifndef MIN
230
 
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
231
 
#endif
232
 
 
233
 
/* compress 512-bits */
234
 
static int sha256_compress(struct sha256_state *md, unsigned char *buf)
235
 
{
236
 
        u32 S[8], W[64], t0, t1;
237
 
        u32 t;
238
 
        int i;
239
 
 
240
 
        /* copy state into S */
241
 
        for (i = 0; i < 8; i++) {
242
 
                S[i] = md->state[i];
243
 
        }
244
 
 
245
 
        /* copy the state into 512-bits into W[0..15] */
246
 
        for (i = 0; i < 16; i++)
247
 
                W[i] = WPA_GET_BE32(buf + (4 * i));
248
 
 
249
 
        /* fill W[16..63] */
250
 
        for (i = 16; i < 64; i++) {
251
 
                W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) +
252
 
                        W[i - 16];
253
 
        }        
254
 
 
255
 
        /* Compress */
256
 
#define RND(a,b,c,d,e,f,g,h,i)                          \
257
 
        t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
258
 
        t1 = Sigma0(a) + Maj(a, b, c);                  \
259
 
        d += t0;                                        \
260
 
        h  = t0 + t1;
261
 
 
262
 
        for (i = 0; i < 64; ++i) {
263
 
                RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i);
264
 
                t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4]; 
265
 
                S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
266
 
        }
267
 
 
268
 
        /* feedback */
269
 
        for (i = 0; i < 8; i++) {
270
 
                md->state[i] = md->state[i] + S[i];
271
 
        }
272
 
        return 0;
273
 
}
274
 
 
275
 
 
276
 
/* Initialize the hash state */
277
 
static void sha256_init(struct sha256_state *md)
278
 
{
279
 
        md->curlen = 0;
280
 
        md->length = 0;
281
 
        md->state[0] = 0x6A09E667UL;
282
 
        md->state[1] = 0xBB67AE85UL;
283
 
        md->state[2] = 0x3C6EF372UL;
284
 
        md->state[3] = 0xA54FF53AUL;
285
 
        md->state[4] = 0x510E527FUL;
286
 
        md->state[5] = 0x9B05688CUL;
287
 
        md->state[6] = 0x1F83D9ABUL;
288
 
        md->state[7] = 0x5BE0CD19UL;
289
 
}
290
 
 
291
 
/**
292
 
   Process a block of memory though the hash
293
 
   @param md     The hash state
294
 
   @param in     The data to hash
295
 
   @param inlen  The length of the data (octets)
296
 
   @return CRYPT_OK if successful
297
 
*/
298
 
static int sha256_process(struct sha256_state *md, const unsigned char *in,
299
 
                          unsigned long inlen)
300
 
{
301
 
        unsigned long n;
302
 
#define block_size 64
303
 
 
304
 
        if (md->curlen > sizeof(md->buf))
305
 
                return -1;
306
 
 
307
 
        while (inlen > 0) {
308
 
                if (md->curlen == 0 && inlen >= block_size) {
309
 
                        if (sha256_compress(md, (unsigned char *) in) < 0)
310
 
                                return -1;
311
 
                        md->length += block_size * 8;
312
 
                        in += block_size;
313
 
                        inlen -= block_size;
314
 
                } else {
315
 
                        n = MIN(inlen, (block_size - md->curlen));
316
 
                        os_memcpy(md->buf + md->curlen, in, n);
317
 
                        md->curlen += n;
318
 
                        in += n;
319
 
                        inlen -= n;
320
 
                        if (md->curlen == block_size) {
321
 
                                if (sha256_compress(md, md->buf) < 0)
322
 
                                        return -1;
323
 
                                md->length += 8 * block_size;
324
 
                                md->curlen = 0;
325
 
                        }
326
 
                }
327
 
        }
328
 
 
329
 
        return 0;
330
 
}
331
 
 
332
 
 
333
 
/**
334
 
   Terminate the hash to get the digest
335
 
   @param md  The hash state
336
 
   @param out [out] The destination of the hash (32 bytes)
337
 
   @return CRYPT_OK if successful
338
 
*/
339
 
static int sha256_done(struct sha256_state *md, unsigned char *out)
340
 
{
341
 
        int i;
342
 
 
343
 
        if (md->curlen >= sizeof(md->buf))
344
 
                return -1;
345
 
 
346
 
        /* increase the length of the message */
347
 
        md->length += md->curlen * 8;
348
 
 
349
 
        /* append the '1' bit */
350
 
        md->buf[md->curlen++] = (unsigned char) 0x80;
351
 
 
352
 
        /* if the length is currently above 56 bytes we append zeros
353
 
         * then compress.  Then we can fall back to padding zeros and length
354
 
         * encoding like normal.
355
 
         */
356
 
        if (md->curlen > 56) {
357
 
                while (md->curlen < 64) {
358
 
                        md->buf[md->curlen++] = (unsigned char) 0;
359
 
                }
360
 
                sha256_compress(md, md->buf);
361
 
                md->curlen = 0;
362
 
        }
363
 
 
364
 
        /* pad upto 56 bytes of zeroes */
365
 
        while (md->curlen < 56) {
366
 
                md->buf[md->curlen++] = (unsigned char) 0;
367
 
        }
368
 
 
369
 
        /* store length */
370
 
        WPA_PUT_BE64(md->buf + 56, md->length);
371
 
        sha256_compress(md, md->buf);
372
 
 
373
 
        /* copy output */
374
 
        for (i = 0; i < 8; i++)
375
 
                WPA_PUT_BE32(out + (4 * i), md->state[i]);
376
 
 
377
 
        return 0;
378
 
}
379
 
 
380
 
/* ===== end - public domain SHA256 implementation ===== */
381
 
 
382
 
#endif /* INTERNAL_SHA256 */