enc_md5.c

Go to the documentation of this file.
00001 /* Module for encryption using MD5.
00002  *
00003  * Modified for Anope.
00004  * (C) 2003-2008 Anope Team
00005  * Contact us at dev@anope.org
00006  *
00007  * Taken from IRC Services and is copyright (c) 1996-2002 Andrew Church.
00008  *     E-mail: <achurch@achurch.org>
00009  * Parts written by Andrew Kempe and others.
00010  * This program is free but copyrighted software; see the file COPYING for
00011  * details.
00012  */
00013 
00014 #include "module.h"
00015 
00016 
00017 /*************************************************************************/
00018 
00019 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
00020 rights reserved.
00021 
00022 License to copy and use this software is granted provided that it
00023 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
00024 Algorithm" in all material mentioning or referencing this software
00025 or this function.
00026 
00027 License is also granted to make and use derivative works provided
00028 that such works are identified as "derived from the RSA Data
00029 Security, Inc. MD5 Message-Digest Algorithm" in all material
00030 mentioning or referencing the derived work.
00031 
00032 RSA Data Security, Inc. makes no representations concerning either
00033 the merchantability of this software or the suitability of this
00034 software for any particular purpose. It is provided "as is"
00035 without express or implied warranty of any kind.
00036 
00037 These notices must be retained in any copies of any part of this
00038 documentation and/or software.
00039  */
00040 
00041 #include <string.h>
00042 
00043 typedef unsigned int UINT4;
00044 
00045 /* MD5 context. */
00046 typedef struct {
00047   UINT4 state[4];                                   /* state (ABCD) */
00048   UINT4 count[2];        /* number of bits, modulo 2^64 (lsb first) */
00049   unsigned char buffer[64];                         /* input buffer */
00050 } MD5_CTX;
00051 
00052 /* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
00053  */
00054 
00055 typedef void *POINTER;
00056 
00057 /* Constants for MD5Transform routine.
00058  */
00059 #define S11 7
00060 #define S12 12
00061 #define S13 17
00062 #define S14 22
00063 #define S21 5
00064 #define S22 9
00065 #define S23 14
00066 #define S24 20
00067 #define S31 4
00068 #define S32 11
00069 #define S33 16
00070 #define S34 23
00071 #define S41 6
00072 #define S42 10
00073 #define S43 15
00074 #define S44 21
00075 
00076 void MD5Transform (UINT4 [4], unsigned char [64]);
00077 void Encode (unsigned char *, UINT4 *, unsigned int);
00078 void Decode (UINT4 *, unsigned char *, unsigned int);
00079 
00080 static unsigned char PADDING[64] = {
00081   0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00082   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00083   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00084 };
00085 
00086 /* F, G, H and I are basic MD5 functions.
00087  */
00088 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
00089 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
00090 #define H(x, y, z) ((x) ^ (y) ^ (z))
00091 #define I(x, y, z) ((y) ^ ((x) | (~z)))
00092 
00093 /* ROTATE_LEFT rotates x left n bits.
00094  */
00095 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
00096 
00097 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
00098 Rotation is separate from addition to prevent recomputation.
00099  */
00100 #define FF(a, b, c, d, x, s, ac) { \
00101  (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
00102  (a) = ROTATE_LEFT ((a), (s)); \
00103  (a) += (b); \
00104   }
00105 #define GG(a, b, c, d, x, s, ac) { \
00106  (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
00107  (a) = ROTATE_LEFT ((a), (s)); \
00108  (a) += (b); \
00109   }
00110 #define HH(a, b, c, d, x, s, ac) { \
00111  (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
00112  (a) = ROTATE_LEFT ((a), (s)); \
00113  (a) += (b); \
00114   }
00115 #define II(a, b, c, d, x, s, ac) { \
00116  (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
00117  (a) = ROTATE_LEFT ((a), (s)); \
00118  (a) += (b); \
00119   }
00120 
00121 /* MD5 initialization. Begins an MD5 operation, writing a new context.
00122  */
00123 void MD5Init (context)
00124 MD5_CTX *context;                                        /* context */
00125 {
00126   context->count[0] = context->count[1] = 0;
00127   /* Load magic initialization constants.
00128 */
00129   context->state[0] = 0x67452301;
00130   context->state[1] = 0xefcdab89;
00131   context->state[2] = 0x98badcfe;
00132   context->state[3] = 0x10325476;
00133 }
00134 
00135 /* MD5 block update operation. Continues an MD5 message-digest
00136   operation, processing another message block, and updating the
00137   context.
00138  */
00139 void MD5Update (context, input, inputLen)
00140 MD5_CTX *context;                                        /* context */
00141 unsigned char *input;                                /* input block */
00142 unsigned int inputLen;                     /* length of input block */
00143 {
00144   unsigned int i, index, partLen;
00145 
00146   /* Compute number of bytes mod 64 */
00147   index = (unsigned int)((context->count[0] >> 3) & 0x3F);
00148 
00149   /* Update number of bits */
00150   if ((context->count[0] += ((UINT4)inputLen << 3))
00151    < ((UINT4)inputLen << 3))
00152  context->count[1]++;
00153   context->count[1] += ((UINT4)inputLen >> 29);
00154 
00155   partLen = 64 - index;
00156 
00157   /* Transform as many times as possible.
00158 */
00159   if (inputLen >= partLen) {
00160  memcpy
00161    ((POINTER)&context->buffer[index], (POINTER)input, partLen);
00162  MD5Transform (context->state, context->buffer);
00163 
00164  for (i = partLen; i + 63 < inputLen; i += 64)
00165    MD5Transform (context->state, &input[i]);
00166 
00167  index = 0;
00168   }
00169   else
00170  i = 0;
00171 
00172   /* Buffer remaining input */
00173   memcpy
00174  ((POINTER)&context->buffer[index], (POINTER)&input[i],
00175   inputLen-i);
00176 }
00177 
00178 /* MD5 finalization. Ends an MD5 message-digest operation, writing the
00179   the message digest and zeroizing the context.
00180  */
00181 void MD5Final (digest, context)
00182 unsigned char digest[16];                         /* message digest */
00183 MD5_CTX *context;                                       /* context */
00184 {
00185   unsigned char bits[8];
00186   unsigned int index, padLen;
00187 
00188   /* Save number of bits */
00189   Encode (bits, context->count, 8);
00190 
00191   /* Pad out to 56 mod 64.
00192 */
00193   index = (unsigned int)((context->count[0] >> 3) & 0x3f);
00194   padLen = (index < 56) ? (56 - index) : (120 - index);
00195   MD5Update (context, PADDING, padLen);
00196 
00197   /* Append length (before padding) */
00198   MD5Update (context, bits, 8);
00199   /* Store state in digest */
00200   Encode (digest, context->state, 16);
00201 
00202   /* Zeroize sensitive information.
00203 */
00204   memset ((POINTER)context, 0, sizeof (*context));
00205 }
00206 
00207 /* MD5 basic transformation. Transforms state based on block.
00208  */
00209 void MD5Transform (state, block)
00210 UINT4 state[4];
00211 unsigned char block[64];
00212 {
00213   UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
00214 
00215   Decode (x, block, 64);
00216 
00217   /* Round 1 */
00218   FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
00219   FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
00220   FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
00221   FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
00222   FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
00223   FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
00224   FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
00225   FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
00226   FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
00227   FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
00228   FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
00229   FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
00230   FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
00231   FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
00232   FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
00233   FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
00234 
00235  /* Round 2 */
00236   GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
00237   GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
00238   GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
00239   GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
00240   GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
00241   GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
00242   GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
00243   GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
00244   GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
00245   GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
00246   GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
00247   GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
00248   GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
00249   GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
00250   GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
00251   GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
00252 
00253   /* Round 3 */
00254   HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
00255   HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
00256   HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
00257   HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
00258   HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
00259   HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
00260   HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
00261   HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
00262   HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
00263   HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
00264   HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
00265   HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
00266   HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
00267   HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
00268   HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
00269   HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
00270 
00271   /* Round 4 */
00272   II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
00273   II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
00274   II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
00275   II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
00276   II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
00277   II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
00278   II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
00279   II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
00280   II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
00281   II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
00282   II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
00283   II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
00284   II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
00285   II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
00286   II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
00287   II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
00288 
00289   state[0] += a;
00290   state[1] += b;
00291   state[2] += c;
00292   state[3] += d;
00293 
00294   /* Zeroize sensitive information.
00295 */
00296   memset ((POINTER)x, 0, sizeof (x));
00297 }
00298 
00299 /* Encodes input (UINT4) into output (unsigned char). Assumes len is
00300   a multiple of 4.
00301  */
00302 void Encode (output, input, len)
00303 unsigned char *output;
00304 UINT4 *input;
00305 unsigned int len;
00306 {
00307   unsigned int i, j;
00308 
00309   for (i = 0, j = 0; j < len; i++, j += 4) {
00310  output[j] = (unsigned char)(input[i] & 0xff);
00311  output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
00312  output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
00313  output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
00314   }
00315 }
00316 
00317 /* Decodes input (unsigned char) into output (UINT4). Assumes len is
00318   a multiple of 4.
00319  */
00320 void Decode (output, input, len)
00321 UINT4 *output;
00322 unsigned char *input;
00323 unsigned int len;
00324 {
00325   unsigned int i, j;
00326 
00327   for (i = 0, j = 0; j < len; i++, j += 4)
00328  output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
00329    (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
00330 }
00331 
00332 /*************************************************************************/
00333 
00334 /* Our own high-level routines.  See encrypt.h for documentation. */
00335 
00336 #define XTOI(c) ((c)>9 ? (c)-'A'+10 : (c)-'0')
00337 
00338 int md5_encrypt(const char *src, int len, char *dest, int size)
00339 {
00340     MD5_CTX context;
00341     char tmp[33];
00342 
00343     if (size < 16)
00344         return -1;
00345 
00346     MD5Init(&context);
00347     MD5Update(&context, src, len);
00348     MD5Final(dest, &context);
00349     
00350     if(debug) {
00351         memset(tmp,0,33);
00352         binary_to_hex(dest,tmp,16);
00353         /* Dont log source if we were encrypting in place :) */
00354         if (memcmp(src, dest, 16) != 0) {
00355             alog("enc_md5: hashed from [%s] to [%s]",src,tmp); 
00356         } else {
00357             alog("enc_md5: hashed password to [%s]",tmp); 
00358         }
00359     }
00360     
00361     return 0;
00362 }
00363 
00364 
00365 int md5_encrypt_in_place(char *buf, int size)
00366 {
00367     return md5_encrypt(buf, strlen(buf), buf, size);
00368 }
00369 
00370 
00371 int md5_encrypt_check_len(int passlen, int bufsize)
00372 {
00373     if (bufsize < 16)
00374         fatal("enc_md5: md5_check_len(): buffer too small (%d)", bufsize);
00375     return 0;
00376 }
00377 
00378 
00379 int md5_decrypt(const char *src, char *dest, int size)
00380 {
00381     return 0;
00382 }
00383 
00384 
00385 int md5_check_password(const char *plaintext, const char *password)
00386 {
00387     char buf[BUFSIZE];
00388 
00389     if (md5_encrypt(plaintext, strlen(plaintext), buf, sizeof(buf)) < 0)
00390         return -1;
00391     if (memcmp(buf, password, 16) == 0)
00392         return 1;
00393     return 0;
00394 }
00395 
00396 /*************************************************************************/
00397 
00398 /* Module stuff. */
00399 
00400 int AnopeInit(int argc, char **argv) {
00401 
00402     moduleAddAuthor("Anope");
00403     moduleAddVersion("$Id: enc_md5.c 1397 2008-06-03 18:44:54Z geniusdex $");
00404     moduleSetType(ENCRYPTION);
00405  
00406     encmodule_encrypt(md5_encrypt);
00407     encmodule_encrypt_in_place(md5_encrypt_in_place);
00408     encmodule_encrypt_check_len(md5_encrypt_check_len);
00409     encmodule_decrypt(md5_decrypt);
00410     encmodule_check_password(md5_check_password);
00411 
00412     return MOD_CONT;
00413 }
00414 
00415 void AnopeFini(void) {
00416     encmodule_encrypt(NULL);
00417     encmodule_encrypt_in_place(NULL);
00418     encmodule_encrypt_check_len(NULL);
00419     encmodule_decrypt(NULL);
00420     encmodule_check_password(NULL);
00421 }
00422 
00423 
00424 
00425 
00426 /*************************************************************************/
00427 

Generated on Sun Oct 5 09:06:54 2008 for Anope by  doxygen 1.5.7.1