Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

md5.c

Go to the documentation of this file.
00001 /* ==================================================================== 
00002  * The Kannel Software License, Version 1.0 
00003  * 
00004  * Copyright (c) 2001-2008 Kannel Group  
00005  * Copyright (c) 1998-2001 WapIT Ltd.   
00006  * All rights reserved. 
00007  * 
00008  * Redistribution and use in source and binary forms, with or without 
00009  * modification, are permitted provided that the following conditions 
00010  * are met: 
00011  * 
00012  * 1. Redistributions of source code must retain the above copyright 
00013  *    notice, this list of conditions and the following disclaimer. 
00014  * 
00015  * 2. Redistributions in binary form must reproduce the above copyright 
00016  *    notice, this list of conditions and the following disclaimer in 
00017  *    the documentation and/or other materials provided with the 
00018  *    distribution. 
00019  * 
00020  * 3. The end-user documentation included with the redistribution, 
00021  *    if any, must include the following acknowledgment: 
00022  *       "This product includes software developed by the 
00023  *        Kannel Group (http://www.kannel.org/)." 
00024  *    Alternately, this acknowledgment may appear in the software itself, 
00025  *    if and wherever such third-party acknowledgments normally appear. 
00026  * 
00027  * 4. The names "Kannel" and "Kannel Group" must not be used to 
00028  *    endorse or promote products derived from this software without 
00029  *    prior written permission. For written permission, please  
00030  *    contact org@kannel.org. 
00031  * 
00032  * 5. Products derived from this software may not be called "Kannel", 
00033  *    nor may "Kannel" appear in their name, without prior written 
00034  *    permission of the Kannel Group. 
00035  * 
00036  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 
00037  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
00038  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
00039  * DISCLAIMED.  IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS 
00040  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,  
00041  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  
00042  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR  
00043  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
00044  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE  
00045  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  
00046  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
00047  * ==================================================================== 
00048  * 
00049  * This software consists of voluntary contributions made by many 
00050  * individuals on behalf of the Kannel Group.  For more information on  
00051  * the Kannel Group, please see <http://www.kannel.org/>. 
00052  * 
00053  * Portions of this software are based upon software originally written at  
00054  * WapIT Ltd., Helsinki, Finland for the Kannel project.  
00055  */ 
00056 
00057 /*
00058  * md5.c - MD5 digest algorithm
00059  *
00060  * The remaining code is the reference MD5 code (md5c.c) from rfc1321
00061  */
00062 
00063 /* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
00064  */
00065 
00066 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
00067    rights reserved.
00068 
00069    License to copy and use this software is granted provided that it
00070    is identified as the "RSA Data Security, Inc. MD5 Message-Digest
00071    Algorithm" in all material mentioning or referencing this software
00072    or this function.
00073 
00074    License is also granted to make and use derivative works provided
00075    that such works are identified as "derived from the RSA Data
00076    Security, Inc. MD5 Message-Digest Algorithm" in all material
00077    mentioning or referencing the derived work.
00078 
00079    RSA Data Security, Inc. makes no representations concerning either
00080    the merchantability of this software or the suitability of this
00081    software for any particular purpose. It is provided "as is"
00082    without express or implied warranty of any kind.
00083 
00084    These notices must be retained in any copies of any part of this
00085    documentation and/or software.
00086  */
00087 
00088 #include <stdio.h>
00089 
00090 #include "gwlib.h"
00091 #include "md5.h"
00092 
00093 /* Declaration of static functions */
00094 
00095 static void md5_digest(char *md5str, unsigned char *digest);
00096 static void md5_init(md5_ctx *);
00097 static void md5_update(md5_ctx *, const unsigned char *, unsigned int);
00098 static void md5_final(unsigned char[16], md5_ctx *);
00099 
00100 
00101 
00102 static void md5_digest(char *md5str, unsigned char *digest)
00103 {
00104     int i;
00105 
00106     for (i = 0; i < 16; i++) {
00107         sprintf(md5str, "%02x", digest[i]);
00108         md5str += 2;
00109     }
00110 
00111     *md5str = '\0';
00112 }
00113 
00114 /* 
00115  * Constants for MD5Transform routine.
00116  */
00117 #define S11 7
00118 #define S12 12
00119 #define S13 17
00120 #define S14 22
00121 #define S21 5
00122 #define S22 9
00123 #define S23 14
00124 #define S24 20
00125 #define S31 4
00126 #define S32 11
00127 #define S33 16
00128 #define S34 23
00129 #define S41 6
00130 #define S42 10
00131 #define S43 15
00132 #define S44 21
00133 
00134 static void md5_transform(unsigned int[4], const unsigned char[64]);
00135 static void md5_encode(unsigned char *, unsigned int *, unsigned int);
00136 static void md5_decode(unsigned int *, const unsigned char *, unsigned int);
00137 
00138 static unsigned char PADDING[64] =
00139 {
00140     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00141     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00142     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00143 };
00144 
00145 /* F, G, H and I are basic MD5 functions.
00146  */
00147 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
00148 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
00149 #define H(x, y, z) ((x) ^ (y) ^ (z))
00150 #define I(x, y, z) ((y) ^ ((x) | (~z)))
00151 
00152 /* ROTATE_LEFT rotates x left n bits.
00153  */
00154 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
00155 
00156 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
00157    Rotation is separate from addition to prevent recomputation.
00158  */
00159 #define FF(a, b, c, d, x, s, ac) { \
00160  (a) += F ((b), (c), (d)) + (x) + (unsigned int)(ac); \
00161  (a) = ROTATE_LEFT ((a), (s)); \
00162  (a) += (b); \
00163   }
00164 #define GG(a, b, c, d, x, s, ac) { \
00165  (a) += G ((b), (c), (d)) + (x) + (unsigned int)(ac); \
00166  (a) = ROTATE_LEFT ((a), (s)); \
00167  (a) += (b); \
00168   }
00169 #define HH(a, b, c, d, x, s, ac) { \
00170  (a) += H ((b), (c), (d)) + (x) + (unsigned int)(ac); \
00171  (a) = ROTATE_LEFT ((a), (s)); \
00172  (a) += (b); \
00173   }
00174 #define II(a, b, c, d, x, s, ac) { \
00175  (a) += I ((b), (c), (d)) + (x) + (unsigned int)(ac); \
00176  (a) = ROTATE_LEFT ((a), (s)); \
00177  (a) += (b); \
00178   }
00179 
00180 static void md5_init(md5_ctx *context)
00181 {
00182     context->count[0] = context->count[1] = 0;
00183     /* Load magic initialization constants. */
00184     context->state[0] = 0x67452301;
00185     context->state[1] = 0xefcdab89;
00186     context->state[2] = 0x98badcfe;
00187     context->state[3] = 0x10325476;
00188 }
00189 
00190 /*
00191  * MD5 block update operation. Continues an MD5 message-digest
00192  * operation, processing another message block, and updating the
00193  * context.
00194  */
00195 static void md5_update(md5_ctx *context, const unsigned char *input,
00196                 unsigned int inputLen)
00197 {
00198     unsigned int i, index, partLen;
00199 
00200     /* Compute number of bytes mod 64 */
00201     index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
00202 
00203     /* Update number of bits */
00204     if ((context->count[0] += ((unsigned int) inputLen << 3))
00205         < ((unsigned int) inputLen << 3))
00206         context->count[1]++;
00207     context->count[1] += ((unsigned int) inputLen >> 29);
00208 
00209     partLen = 64 - index;
00210 
00211     /* Transform as many times as possible. */
00212     if (inputLen >= partLen) {
00213         memcpy((unsigned char*) & context->buffer[index], 
00214                (unsigned char*) input, partLen);
00215         md5_transform(context->state, context->buffer);
00216 
00217         for (i = partLen; i + 63 < inputLen; i += 64)
00218             md5_transform(context->state, &input[i]);
00219 
00220         index = 0;
00221     } else
00222         i = 0;
00223 
00224     /* Buffer remaining input */
00225     memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
00226            inputLen - i);
00227 }
00228 
00229 /*
00230    MD5 finalization. Ends an MD5 message-digest operation, writing the
00231    the message digest and zeroizing the context.
00232  */
00233 static void md5_final(unsigned char digest[16], md5_ctx *context)
00234 {
00235     unsigned char bits[8];
00236     unsigned int index, padLen;
00237 
00238     /* Save number of bits */
00239     md5_encode(bits, context->count, 8);
00240 
00241     /* Pad out to 56 mod 64.
00242      */
00243     index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
00244     padLen = (index < 56) ? (56 - index) : (120 - index);
00245     md5_update(context, PADDING, padLen);
00246 
00247     /* Append length (before padding) */
00248     md5_update(context, bits, 8);
00249 
00250     /* Store state in digest */
00251     md5_encode(digest, context->state, 16);
00252 
00253     /* Zeroize sensitive information.
00254      */
00255     memset((unsigned char*) context, 0, sizeof(*context));
00256 }
00257 
00258 
00259 /* 
00260  * MD5 basic transformation. Transforms state based on block.
00261  */
00262 static void md5_transform(state, block)
00263 unsigned int state[4];
00264 const unsigned char block[64];
00265 {
00266     unsigned int a = state[0], b = state[1], c = state[2], d = state[3], x[16];
00267 
00268     md5_decode(x, block, 64);
00269 
00270     /* Round 1 */
00271     FF(a, b, c, d, x[0], S11, 0xd76aa478);  /* 1 */
00272     FF(d, a, b, c, x[1], S12, 0xe8c7b756);  /* 2 */
00273     FF(c, d, a, b, x[2], S13, 0x242070db);  /* 3 */
00274     FF(b, c, d, a, x[3], S14, 0xc1bdceee);  /* 4 */
00275     FF(a, b, c, d, x[4], S11, 0xf57c0faf);  /* 5 */
00276     FF(d, a, b, c, x[5], S12, 0x4787c62a);  /* 6 */
00277     FF(c, d, a, b, x[6], S13, 0xa8304613);  /* 7 */
00278     FF(b, c, d, a, x[7], S14, 0xfd469501);  /* 8 */
00279     FF(a, b, c, d, x[8], S11, 0x698098d8);  /* 9 */
00280     FF(d, a, b, c, x[9], S12, 0x8b44f7af);  /* 10 */
00281     FF(c, d, a, b, x[10], S13, 0xffff5bb1);     /* 11 */
00282     FF(b, c, d, a, x[11], S14, 0x895cd7be);     /* 12 */
00283     FF(a, b, c, d, x[12], S11, 0x6b901122);     /* 13 */
00284     FF(d, a, b, c, x[13], S12, 0xfd987193);     /* 14 */
00285     FF(c, d, a, b, x[14], S13, 0xa679438e);     /* 15 */
00286     FF(b, c, d, a, x[15], S14, 0x49b40821);     /* 16 */
00287 
00288     /* Round 2 */
00289     GG(a, b, c, d, x[1], S21, 0xf61e2562);  /* 17 */
00290     GG(d, a, b, c, x[6], S22, 0xc040b340);  /* 18 */
00291     GG(c, d, a, b, x[11], S23, 0x265e5a51);     /* 19 */
00292     GG(b, c, d, a, x[0], S24, 0xe9b6c7aa);  /* 20 */
00293     GG(a, b, c, d, x[5], S21, 0xd62f105d);  /* 21 */
00294     GG(d, a, b, c, x[10], S22, 0x2441453);  /* 22 */
00295     GG(c, d, a, b, x[15], S23, 0xd8a1e681);     /* 23 */
00296     GG(b, c, d, a, x[4], S24, 0xe7d3fbc8);  /* 24 */
00297     GG(a, b, c, d, x[9], S21, 0x21e1cde6);  /* 25 */
00298     GG(d, a, b, c, x[14], S22, 0xc33707d6);     /* 26 */
00299     GG(c, d, a, b, x[3], S23, 0xf4d50d87);  /* 27 */
00300     GG(b, c, d, a, x[8], S24, 0x455a14ed);  /* 28 */
00301     GG(a, b, c, d, x[13], S21, 0xa9e3e905);     /* 29 */
00302     GG(d, a, b, c, x[2], S22, 0xfcefa3f8);  /* 30 */
00303     GG(c, d, a, b, x[7], S23, 0x676f02d9);  /* 31 */
00304     GG(b, c, d, a, x[12], S24, 0x8d2a4c8a);     /* 32 */
00305 
00306     /* Round 3 */
00307     HH(a, b, c, d, x[5], S31, 0xfffa3942);  /* 33 */
00308     HH(d, a, b, c, x[8], S32, 0x8771f681);  /* 34 */
00309     HH(c, d, a, b, x[11], S33, 0x6d9d6122);     /* 35 */
00310     HH(b, c, d, a, x[14], S34, 0xfde5380c);     /* 36 */
00311     HH(a, b, c, d, x[1], S31, 0xa4beea44);  /* 37 */
00312     HH(d, a, b, c, x[4], S32, 0x4bdecfa9);  /* 38 */
00313     HH(c, d, a, b, x[7], S33, 0xf6bb4b60);  /* 39 */
00314     HH(b, c, d, a, x[10], S34, 0xbebfbc70);     /* 40 */
00315     HH(a, b, c, d, x[13], S31, 0x289b7ec6);     /* 41 */
00316     HH(d, a, b, c, x[0], S32, 0xeaa127fa);  /* 42 */
00317     HH(c, d, a, b, x[3], S33, 0xd4ef3085);  /* 43 */
00318     HH(b, c, d, a, x[6], S34, 0x4881d05);   /* 44 */
00319     HH(a, b, c, d, x[9], S31, 0xd9d4d039);  /* 45 */
00320     HH(d, a, b, c, x[12], S32, 0xe6db99e5);     /* 46 */
00321     HH(c, d, a, b, x[15], S33, 0x1fa27cf8);     /* 47 */
00322     HH(b, c, d, a, x[2], S34, 0xc4ac5665);  /* 48 */
00323 
00324     /* Round 4 */
00325     II(a, b, c, d, x[0], S41, 0xf4292244);  /* 49 */
00326     II(d, a, b, c, x[7], S42, 0x432aff97);  /* 50 */
00327     II(c, d, a, b, x[14], S43, 0xab9423a7);     /* 51 */
00328     II(b, c, d, a, x[5], S44, 0xfc93a039);  /* 52 */
00329     II(a, b, c, d, x[12], S41, 0x655b59c3);     /* 53 */
00330     II(d, a, b, c, x[3], S42, 0x8f0ccc92);  /* 54 */
00331     II(c, d, a, b, x[10], S43, 0xffeff47d);     /* 55 */
00332     II(b, c, d, a, x[1], S44, 0x85845dd1);  /* 56 */
00333     II(a, b, c, d, x[8], S41, 0x6fa87e4f);  /* 57 */
00334     II(d, a, b, c, x[15], S42, 0xfe2ce6e0);     /* 58 */
00335     II(c, d, a, b, x[6], S43, 0xa3014314);  /* 59 */
00336     II(b, c, d, a, x[13], S44, 0x4e0811a1);     /* 60 */
00337     II(a, b, c, d, x[4], S41, 0xf7537e82);  /* 61 */
00338     II(d, a, b, c, x[11], S42, 0xbd3af235);     /* 62 */
00339     II(c, d, a, b, x[2], S43, 0x2ad7d2bb);  /* 63 */
00340     II(b, c, d, a, x[9], S44, 0xeb86d391);  /* 64 */
00341 
00342     state[0] += a;
00343     state[1] += b;
00344     state[2] += c;
00345     state[3] += d;
00346 
00347     /* Zeroize sensitive information. */
00348     memset((unsigned char*) x, 0, sizeof(x));
00349 }
00350 
00351 /* 
00352    Encodes input (unsigned int) into output (unsigned char). Assumes len is
00353    a multiple of 4.
00354  */
00355 static void md5_encode(output, input, len)
00356 unsigned char *output;
00357 unsigned int *input;
00358 unsigned int len;
00359 {
00360     unsigned int i, j;
00361 
00362     for (i = 0, j = 0; j < len; i++, j += 4) {
00363         output[j] = (unsigned char) (input[i] & 0xff);
00364         output[j + 1] = (unsigned char) ((input[i] >> 8) & 0xff);
00365         output[j + 2] = (unsigned char) ((input[i] >> 16) & 0xff);
00366         output[j + 3] = (unsigned char) ((input[i] >> 24) & 0xff);
00367     }
00368 }
00369 
00370 /* 
00371    Decodes input (unsigned char) into output (unsigned int). Assumes len is
00372    a multiple of 4.
00373  */
00374 static void md5_decode(output, input, len)
00375 unsigned int *output;
00376 const unsigned char *input;
00377 unsigned int len;
00378 {
00379     unsigned int i, j;
00380 
00381     for (i = 0, j = 0; j < len; i++, j += 4)
00382         output[i] = ((unsigned int) input[j]) | (((unsigned int) input[j + 1]) << 8) |
00383             (((unsigned int) input[j + 2]) << 16) | (((unsigned int) input[j + 3]) << 24);
00384 }
00385 
00386 
00387 Octstr *md5(Octstr *data)
00388 {
00389     md5_ctx context;
00390     unsigned char digest[16];
00391     Octstr *enc;
00392 
00393     if (data == NULL)
00394         return NULL;
00395 
00396     md5_init(&context);
00397     md5_update(&context, octstr_get_cstr(data), octstr_len(data));
00398     md5_final(digest, &context);
00399 
00400     enc = octstr_create_from_data(digest, 16); 
00401 
00402     return enc; 
00403 }
00404 
00405 
00406 Octstr *md5digest(Octstr *data)
00407 {
00408     char md5str[33];
00409     Octstr *digest;
00410 
00411     if (data == NULL)
00412         return NULL;
00413 
00414     md5str[0] = '\0';
00415     digest = md5(data);
00416     md5_digest(md5str, octstr_get_cstr(digest));
00417     octstr_destroy(digest);
00418 
00419     digest = octstr_create(md5str);
00420 
00421     return digest;
00422 }
00423 
00424 
00425 
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.