enc_old.c

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

Generated on Sun Dec 30 09:26:47 2007 for Anope by  doxygen 1.5.1-20070107