root/modules/md5.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hmac_md5_vector
  2. hmac_md5
  3. md5_vector
  4. byteReverse
  5. MD5Init
  6. MD5Update
  7. MD5Final
  8. MD5Transform

   1 /*
   2  * MD5 hash implementation and interface functions
   3  * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
   4  *
   5  * This program is free software; you can redistribute it and/or modify
   6  * it under the terms of the GNU General Public License version 2 as
   7  * published by the Free Software Foundation.
   8  *
   9  * Alternatively, this software may be distributed under the terms of BSD
  10  * license.
  11  *
  12  * See README and COPYING for more details.
  13   * modified for CHDK by buttim@hotmail.com
  14  */
  15 
  16 #include "eyefi.h"
  17 
  18 #include <string.h>
  19 //#include <unistd.h>
  20 
  21 /**
  22  * hmac_md5_vector - HMAC-MD5 over data vector (RFC 2104)
  23  * @key: Key for HMAC operations
  24  * @key_len: Length of the key in bytes
  25  * @num_elem: Number of elements in the data vector
  26  * @addr: Pointers to the data areas
  27  * @len: Lengths of the data blocks
  28  * @mac: Buffer for the hash (16 bytes)
  29  */
  30 void hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
  31                      const u8 *addr[], const size_t *len, u8 *mac)
  32 {
  33         u8 k_pad[64]; /* padding - key XORd with ipad/opad */
  34         u8 tk[16];
  35         const u8 *_addr[6];
  36         size_t i, _len[6];
  37 
  38         if (num_elem > 5) {
  39                 /*
  40                  * Fixed limit on the number of fragments to avoid having to
  41                  * allocate memory (which could fail).
  42                  */
  43                 return;
  44         }
  45 
  46         /* if key is longer than 64 bytes reset it to key = MD5(key) */
  47         if (key_len > 64) {
  48                 md5_vector(1, &key, &key_len, tk);
  49                 key = tk;
  50                 key_len = 16;
  51         }
  52 
  53         /* the HMAC_MD5 transform looks like:
  54          *
  55          * MD5(K XOR opad, MD5(K XOR ipad, text))
  56          *
  57          * where K is an n byte key
  58          * ipad is the byte 0x36 repeated 64 times
  59          * opad is the byte 0x5c repeated 64 times
  60          * and text is the data being protected */
  61 
  62         /* start out by storing key in ipad */
  63         os_memset(k_pad, 0, sizeof(k_pad));
  64         os_memcpy(k_pad, key, key_len);
  65 
  66         /* XOR key with ipad values */
  67         for (i = 0; i < 64; i++)
  68                 k_pad[i] ^= 0x36;
  69 
  70         /* perform inner MD5 */
  71         _addr[0] = k_pad;
  72         _len[0] = 64;
  73         for (i = 0; i < num_elem; i++) {
  74                 _addr[i + 1] = addr[i];
  75                 _len[i + 1] = len[i];
  76         }
  77         md5_vector(1 + num_elem, _addr, _len, mac);
  78 
  79         os_memset(k_pad, 0, sizeof(k_pad));
  80         os_memcpy(k_pad, key, key_len);
  81         /* XOR key with opad values */
  82         for (i = 0; i < 64; i++)
  83                 k_pad[i] ^= 0x5c;
  84 
  85         /* perform outer MD5 */
  86         _addr[0] = k_pad;
  87         _len[0] = 64;
  88         _addr[1] = mac;
  89         _len[1] = MD5_MAC_LEN;
  90         md5_vector(2, _addr, _len, mac);
  91 }
  92 
  93 
  94 /**
  95  * hmac_md5 - HMAC-MD5 over data buffer (RFC 2104)
  96  * @key: Key for HMAC operations
  97  * @key_len: Length of the key in bytes
  98  * @data: Pointers to the data area
  99  * @data_len: Length of the data area
 100  * @mac: Buffer for the hash (16 bytes)
 101  */
 102 void hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
 103               u8 *mac)
 104 {
 105         hmac_md5_vector(key, key_len, 1, &data, &data_len, mac);
 106 }
 107 
 108 #define INTERNAL_MD5 1
 109 
 110 #ifdef INTERNAL_MD5
 111 
 112 struct MD5Context {
 113         u32 buf[4];
 114         u32 bits[2];
 115         u8 in[64];
 116 };
 117 
 118 #ifndef CONFIG_CRYPTO_INTERNAL
 119 static void MD5Init(struct MD5Context *context);
 120 static void MD5Update(struct MD5Context *context, unsigned char const *buf,
 121                           unsigned len);
 122 static void MD5Final(unsigned char digest[16], struct MD5Context *context);
 123 #endif /* CONFIG_CRYPTO_INTERNAL */
 124 static void MD5Transform(u32 buf[4], u32 const in[16]);
 125 
 126 
 127 typedef struct MD5Context MD5_CTX;
 128 
 129 
 130 /**
 131  * md5_vector - MD5 hash for data vector
 132  * @num_elem: Number of elements in the data vector
 133  * @addr: Pointers to the data areas
 134  * @len: Lengths of the data blocks
 135  * @mac: Buffer for the hash
 136  */
 137 void md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 138 {
 139         MD5_CTX ctx;
 140         size_t i;
 141 
 142         MD5Init(&ctx);
 143         for (i = 0; i < num_elem; i++)
 144                 MD5Update(&ctx, addr[i], len[i]);
 145         MD5Final(mac, &ctx);
 146 }
 147 
 148 
 149 /* ===== start - public domain MD5 implementation ===== */
 150 /*
 151  * This code implements the MD5 message-digest algorithm.
 152  * The algorithm is due to Ron Rivest.  This code was
 153  * written by Colin Plumb in 1993, no copyright is claimed.
 154  * This code is in the public domain; do with it what you wish.
 155  *
 156  * Equivalent code is available from RSA Data Security, Inc.
 157  * This code has been tested against that, and is equivalent,
 158  * except that you don't need to include two pages of legalese
 159  * with every copy.
 160  *
 161  * To compute the message digest of a chunk of bytes, declare an
 162  * MD5Context structure, pass it to MD5Init, call MD5Update as
 163  * needed on buffers full of bytes, and then call MD5Final, which
 164  * will fill a supplied 16-byte array with the digest.
 165  */
 166 
 167 #ifndef WORDS_BIGENDIAN
 168 #define byteReverse(buf, len)   /* Nothing */
 169 #else
 170 /*
 171  * Note: this code is harmless on little-endian machines.
 172  */
 173 static void byteReverse(unsigned char *buf, unsigned longs)
 174 {
 175     u32 t;
 176     do {
 177         t = (u32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
 178             ((unsigned) buf[1] << 8 | buf[0]);
 179         *(u32 *) buf = t;
 180         buf += 4;
 181     } while (--longs);
 182 }
 183 #endif
 184 
 185 /*
 186  * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
 187  * initialization constants.
 188  */
 189 void MD5Init(struct MD5Context *ctx)
 190 {
 191     ctx->buf[0] = 0x67452301;
 192     ctx->buf[1] = 0xefcdab89;
 193     ctx->buf[2] = 0x98badcfe;
 194     ctx->buf[3] = 0x10325476;
 195 
 196     ctx->bits[0] = 0;
 197     ctx->bits[1] = 0;
 198 }
 199 
 200 /*
 201  * Update context to reflect the concatenation of another buffer full
 202  * of bytes.
 203  */
 204 void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
 205 {
 206     u32 t;
 207 
 208     /* Update bitcount */
 209 
 210     t = ctx->bits[0];
 211     if ((ctx->bits[0] = t + ((u32) len << 3)) < t)
 212         ctx->bits[1]++;         /* Carry from low to high */
 213     ctx->bits[1] += len >> 29;
 214 
 215     t = (t >> 3) & 0x3f;        /* Bytes already in shsInfo->data */
 216 
 217     /* Handle any leading odd-sized chunks */
 218 
 219     if (t) {
 220         unsigned char *p = (unsigned char *) ctx->in + t;
 221 
 222         t = 64 - t;
 223         if (len < t) {
 224             os_memcpy(p, buf, len);
 225             return;
 226         }
 227         os_memcpy(p, buf, t);
 228         byteReverse(ctx->in, 16);
 229         MD5Transform(ctx->buf, (u32 *) ctx->in);
 230         buf += t;
 231         len -= t;
 232     }
 233     /* Process data in 64-byte chunks */
 234 
 235     while (len >= 64) {
 236         os_memcpy(ctx->in, buf, 64);
 237         byteReverse(ctx->in, 16);
 238         MD5Transform(ctx->buf, (u32 *) ctx->in);
 239         buf += 64;
 240         len -= 64;
 241     }
 242 
 243     /* Handle any remaining bytes of data. */
 244 
 245     os_memcpy(ctx->in, buf, len);
 246 }
 247 
 248 /*
 249  * Final wrapup - pad to 64-byte boundary with the bit pattern
 250  * 1 0* (64-bit count of bits processed, MSB-first)
 251  */
 252 void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
 253 {
 254     unsigned count;
 255     unsigned char *p;
 256 
 257     /* Compute number of bytes mod 64 */
 258     count = (ctx->bits[0] >> 3) & 0x3F;
 259 
 260     /* Set the first char of padding to 0x80.  This is safe since there is
 261        always at least one byte free */
 262     p = ctx->in + count;
 263     *p++ = 0x80;
 264 
 265     /* Bytes of padding needed to make 64 bytes */
 266     count = 64 - 1 - count;
 267 
 268     /* Pad out to 56 mod 64 */
 269     if (count < 8) {
 270         /* Two lots of padding:  Pad the first block to 64 bytes */
 271         os_memset(p, 0, count);
 272         byteReverse(ctx->in, 16);
 273         MD5Transform(ctx->buf, (u32 *) ctx->in);
 274 
 275         /* Now fill the next block with 56 bytes */
 276         os_memset(ctx->in, 0, 56);
 277     } else {
 278         /* Pad block to 56 bytes */
 279         os_memset(p, 0, count - 8);
 280     }
 281     byteReverse(ctx->in, 14);
 282 
 283     /* Append length in bits and transform */
 284     ((u32 *) ctx->in)[14] = ctx->bits[0];
 285     ((u32 *) ctx->in)[15] = ctx->bits[1];
 286 
 287     MD5Transform(ctx->buf, (u32 *) ctx->in);
 288     byteReverse((unsigned char *) ctx->buf, 4);
 289     os_memcpy(digest, ctx->buf, 16);
 290     os_memset(ctx, 0, sizeof(struct MD5Context));       /* In case it's sensitive */
 291 }
 292 
 293 /* The four core functions - F1 is optimized somewhat */
 294 
 295 /* #define F1(x, y, z) (x & y | ~x & z) */
 296 #define F1(x, y, z) (z ^ (x & (y ^ z)))
 297 #define F2(x, y, z) F1(z, x, y)
 298 #define F3(x, y, z) (x ^ y ^ z)
 299 #define F4(x, y, z) (y ^ (x | ~z))
 300 
 301 /* This is the central step in the MD5 algorithm. */
 302 #define MD5STEP(f, w, x, y, z, data, s) \
 303         ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
 304 
 305 /*
 306  * The core of the MD5 algorithm, this alters an existing MD5 hash to
 307  * reflect the addition of 16 longwords of new data.  MD5Update blocks
 308  * the data and converts bytes into longwords for this routine.
 309  */
 310 static void MD5Transform(u32 buf[4], u32 const in[16])
 311 {
 312     register u32 a, b, c, d;
 313 
 314     a = buf[0];
 315     b = buf[1];
 316     c = buf[2];
 317     d = buf[3];
 318 
 319     MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
 320     MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
 321     MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
 322     MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
 323     MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
 324     MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
 325     MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
 326     MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
 327     MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
 328     MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
 329     MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
 330     MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
 331     MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
 332     MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
 333     MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
 334     MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
 335 
 336     MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
 337     MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
 338     MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
 339     MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
 340     MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
 341     MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
 342     MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
 343     MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
 344     MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
 345     MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
 346     MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
 347     MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
 348     MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
 349     MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
 350     MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
 351     MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
 352 
 353     MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
 354     MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
 355     MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
 356     MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
 357     MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
 358     MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
 359     MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
 360     MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
 361     MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
 362     MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
 363     MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
 364     MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
 365     MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
 366     MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
 367     MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
 368     MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
 369 
 370     MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
 371     MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
 372     MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
 373     MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
 374     MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
 375     MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
 376     MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
 377     MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
 378     MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
 379     MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
 380     MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
 381     MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
 382     MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
 383     MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
 384     MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
 385     MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
 386 
 387     buf[0] += a;
 388     buf[1] += b;
 389     buf[2] += c;
 390     buf[3] += d;
 391 }
 392 /* ===== end - public domain MD5 implementation ===== */
 393 
 394 #endif /* INTERNAL_MD5 */

/* [<][>][^][v][top][bottom][index][help] */