jabberd2
2.2.16
|
00001 /* 00002 Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved. 00003 00004 This software is provided 'as-is', without any express or implied 00005 warranty. In no event will the authors be held liable for any damages 00006 arising from the use of this software. 00007 00008 Permission is granted to anyone to use this software for any purpose, 00009 including commercial applications, and to alter it and redistribute it 00010 freely, subject to the following restrictions: 00011 00012 1. The origin of this software must not be misrepresented; you must not 00013 claim that you wrote the original software. If you use this software 00014 in a product, an acknowledgment in the product documentation would be 00015 appreciated but is not required. 00016 2. Altered source versions must be plainly marked as such, and must not be 00017 misrepresented as being the original software. 00018 3. This notice may not be removed or altered from any source distribution. 00019 00020 L. Peter Deutsch 00021 ghost@aladdin.com 00022 00023 */ 00024 /* $Id: md5.c,v 1.5 2005/06/02 04:48:25 zion Exp $ */ 00025 /* 00026 Independent implementation of MD5 (RFC 1321). 00027 00028 This code implements the MD5 Algorithm defined in RFC 1321, whose 00029 text is available at 00030 http://www.ietf.org/rfc/rfc1321.txt 00031 The code is derived from the text of the RFC, including the test suite 00032 (section A.5) but excluding the rest of Appendix A. It does not include 00033 any code or documentation that is identified in the RFC as being 00034 copyrighted. 00035 00036 The original and principal author of md5.c is L. Peter Deutsch 00037 <ghost@aladdin.com>. Other authors are noted in the change history 00038 that follows (in reverse chronological order): 00039 00040 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order 00041 either statically or dynamically; added missing #include <string.h> 00042 in library. 00043 2002-03-11 lpd Corrected argument list for main(), and added int return 00044 type, in test program and T value program. 00045 2002-02-21 lpd Added missing #include <stdio.h> in test program. 00046 2000-07-03 lpd Patched to eliminate warnings about "constant is 00047 unsigned in ANSI C, signed in traditional"; made test program 00048 self-checking. 00049 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 00050 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). 00051 1999-05-03 lpd Original version. 00052 */ 00053 00054 #include "md5.h" 00055 00056 #ifndef HAVE_SSL /* only if we do not use OpenSSL provided implementation */ 00057 00058 #include <string.h> 00059 00060 #undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ 00061 #ifdef ARCH_IS_BIG_ENDIAN 00062 # define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) 00063 #else 00064 # define BYTE_ORDER 0 00065 #endif 00066 00067 #define T_MASK ((md5_word_t)~0) 00068 #define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) 00069 #define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) 00070 #define T3 0x242070db 00071 #define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) 00072 #define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) 00073 #define T6 0x4787c62a 00074 #define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) 00075 #define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) 00076 #define T9 0x698098d8 00077 #define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) 00078 #define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) 00079 #define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) 00080 #define T13 0x6b901122 00081 #define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) 00082 #define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) 00083 #define T16 0x49b40821 00084 #define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) 00085 #define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) 00086 #define T19 0x265e5a51 00087 #define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) 00088 #define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) 00089 #define T22 0x02441453 00090 #define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) 00091 #define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) 00092 #define T25 0x21e1cde6 00093 #define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) 00094 #define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) 00095 #define T28 0x455a14ed 00096 #define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) 00097 #define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) 00098 #define T31 0x676f02d9 00099 #define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) 00100 #define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) 00101 #define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) 00102 #define T35 0x6d9d6122 00103 #define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) 00104 #define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) 00105 #define T38 0x4bdecfa9 00106 #define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) 00107 #define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) 00108 #define T41 0x289b7ec6 00109 #define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) 00110 #define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) 00111 #define T44 0x04881d05 00112 #define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) 00113 #define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) 00114 #define T47 0x1fa27cf8 00115 #define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) 00116 #define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) 00117 #define T50 0x432aff97 00118 #define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) 00119 #define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) 00120 #define T53 0x655b59c3 00121 #define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) 00122 #define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) 00123 #define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) 00124 #define T57 0x6fa87e4f 00125 #define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) 00126 #define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) 00127 #define T60 0x4e0811a1 00128 #define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) 00129 #define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) 00130 #define T63 0x2ad7d2bb 00131 #define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) 00132 00133 00134 static void 00135 md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) 00136 { 00137 md5_word_t 00138 a = pms->abcd[0], b = pms->abcd[1], 00139 c = pms->abcd[2], d = pms->abcd[3]; 00140 md5_word_t t; 00141 #if BYTE_ORDER > 0 00142 /* Define storage only for big-endian CPUs. */ 00143 md5_word_t X[16]; 00144 #else 00145 /* Define storage for little-endian or both types of CPUs. */ 00146 md5_word_t xbuf[16]; 00147 const md5_word_t *X; 00148 #endif 00149 00150 { 00151 #if BYTE_ORDER == 0 00152 /* 00153 * Determine dynamically whether this is a big-endian or 00154 * little-endian machine, since we can use a more efficient 00155 * algorithm on the latter. 00156 */ 00157 static const int w = 1; 00158 00159 if (*((const md5_byte_t *)&w)) /* dynamic little-endian */ 00160 #endif 00161 #if BYTE_ORDER <= 0 /* little-endian */ 00162 { 00163 /* 00164 * On little-endian machines, we can process properly aligned 00165 * data without copying it. 00166 */ 00167 if (!((data - (const md5_byte_t *)0) & 3)) { 00168 /* data are properly aligned */ 00169 X = (const md5_word_t *)data; 00170 } else { 00171 /* not aligned */ 00172 memcpy(xbuf, data, 64); 00173 X = xbuf; 00174 } 00175 } 00176 #endif 00177 #if BYTE_ORDER == 0 00178 else /* dynamic big-endian */ 00179 #endif 00180 #if BYTE_ORDER >= 0 /* big-endian */ 00181 { 00182 /* 00183 * On big-endian machines, we must arrange the bytes in the 00184 * right order. 00185 */ 00186 const md5_byte_t *xp = data; 00187 int i; 00188 00189 # if BYTE_ORDER == 0 00190 X = xbuf; /* (dynamic only) */ 00191 # else 00192 # define xbuf X /* (static only) */ 00193 # endif 00194 for (i = 0; i < 16; ++i, xp += 4) 00195 xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); 00196 } 00197 #endif 00198 } 00199 00200 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) 00201 00202 /* Round 1. */ 00203 /* Let [abcd k s i] denote the operation 00204 a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ 00205 #define F(x, y, z) (((x) & (y)) | (~(x) & (z))) 00206 #define SET(a, b, c, d, k, s, Ti)\ 00207 t = a + F(b,c,d) + X[k] + Ti;\ 00208 a = ROTATE_LEFT(t, s) + b 00209 /* Do the following 16 operations. */ 00210 SET(a, b, c, d, 0, 7, T1); 00211 SET(d, a, b, c, 1, 12, T2); 00212 SET(c, d, a, b, 2, 17, T3); 00213 SET(b, c, d, a, 3, 22, T4); 00214 SET(a, b, c, d, 4, 7, T5); 00215 SET(d, a, b, c, 5, 12, T6); 00216 SET(c, d, a, b, 6, 17, T7); 00217 SET(b, c, d, a, 7, 22, T8); 00218 SET(a, b, c, d, 8, 7, T9); 00219 SET(d, a, b, c, 9, 12, T10); 00220 SET(c, d, a, b, 10, 17, T11); 00221 SET(b, c, d, a, 11, 22, T12); 00222 SET(a, b, c, d, 12, 7, T13); 00223 SET(d, a, b, c, 13, 12, T14); 00224 SET(c, d, a, b, 14, 17, T15); 00225 SET(b, c, d, a, 15, 22, T16); 00226 #undef SET 00227 00228 /* Round 2. */ 00229 /* Let [abcd k s i] denote the operation 00230 a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ 00231 #define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) 00232 #define SET(a, b, c, d, k, s, Ti)\ 00233 t = a + G(b,c,d) + X[k] + Ti;\ 00234 a = ROTATE_LEFT(t, s) + b 00235 /* Do the following 16 operations. */ 00236 SET(a, b, c, d, 1, 5, T17); 00237 SET(d, a, b, c, 6, 9, T18); 00238 SET(c, d, a, b, 11, 14, T19); 00239 SET(b, c, d, a, 0, 20, T20); 00240 SET(a, b, c, d, 5, 5, T21); 00241 SET(d, a, b, c, 10, 9, T22); 00242 SET(c, d, a, b, 15, 14, T23); 00243 SET(b, c, d, a, 4, 20, T24); 00244 SET(a, b, c, d, 9, 5, T25); 00245 SET(d, a, b, c, 14, 9, T26); 00246 SET(c, d, a, b, 3, 14, T27); 00247 SET(b, c, d, a, 8, 20, T28); 00248 SET(a, b, c, d, 13, 5, T29); 00249 SET(d, a, b, c, 2, 9, T30); 00250 SET(c, d, a, b, 7, 14, T31); 00251 SET(b, c, d, a, 12, 20, T32); 00252 #undef SET 00253 00254 /* Round 3. */ 00255 /* Let [abcd k s t] denote the operation 00256 a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ 00257 #define H(x, y, z) ((x) ^ (y) ^ (z)) 00258 #define SET(a, b, c, d, k, s, Ti)\ 00259 t = a + H(b,c,d) + X[k] + Ti;\ 00260 a = ROTATE_LEFT(t, s) + b 00261 /* Do the following 16 operations. */ 00262 SET(a, b, c, d, 5, 4, T33); 00263 SET(d, a, b, c, 8, 11, T34); 00264 SET(c, d, a, b, 11, 16, T35); 00265 SET(b, c, d, a, 14, 23, T36); 00266 SET(a, b, c, d, 1, 4, T37); 00267 SET(d, a, b, c, 4, 11, T38); 00268 SET(c, d, a, b, 7, 16, T39); 00269 SET(b, c, d, a, 10, 23, T40); 00270 SET(a, b, c, d, 13, 4, T41); 00271 SET(d, a, b, c, 0, 11, T42); 00272 SET(c, d, a, b, 3, 16, T43); 00273 SET(b, c, d, a, 6, 23, T44); 00274 SET(a, b, c, d, 9, 4, T45); 00275 SET(d, a, b, c, 12, 11, T46); 00276 SET(c, d, a, b, 15, 16, T47); 00277 SET(b, c, d, a, 2, 23, T48); 00278 #undef SET 00279 00280 /* Round 4. */ 00281 /* Let [abcd k s t] denote the operation 00282 a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ 00283 #define I(x, y, z) ((y) ^ ((x) | ~(z))) 00284 #define SET(a, b, c, d, k, s, Ti)\ 00285 t = a + I(b,c,d) + X[k] + Ti;\ 00286 a = ROTATE_LEFT(t, s) + b 00287 /* Do the following 16 operations. */ 00288 SET(a, b, c, d, 0, 6, T49); 00289 SET(d, a, b, c, 7, 10, T50); 00290 SET(c, d, a, b, 14, 15, T51); 00291 SET(b, c, d, a, 5, 21, T52); 00292 SET(a, b, c, d, 12, 6, T53); 00293 SET(d, a, b, c, 3, 10, T54); 00294 SET(c, d, a, b, 10, 15, T55); 00295 SET(b, c, d, a, 1, 21, T56); 00296 SET(a, b, c, d, 8, 6, T57); 00297 SET(d, a, b, c, 15, 10, T58); 00298 SET(c, d, a, b, 6, 15, T59); 00299 SET(b, c, d, a, 13, 21, T60); 00300 SET(a, b, c, d, 4, 6, T61); 00301 SET(d, a, b, c, 11, 10, T62); 00302 SET(c, d, a, b, 2, 15, T63); 00303 SET(b, c, d, a, 9, 21, T64); 00304 #undef SET 00305 00306 /* Then perform the following additions. (That is increment each 00307 of the four registers by the value it had before this block 00308 was started.) */ 00309 pms->abcd[0] += a; 00310 pms->abcd[1] += b; 00311 pms->abcd[2] += c; 00312 pms->abcd[3] += d; 00313 } 00314 00315 void 00316 md5_init(md5_state_t *pms) 00317 { 00318 pms->count[0] = pms->count[1] = 0; 00319 pms->abcd[0] = 0x67452301; 00320 pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; 00321 pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; 00322 pms->abcd[3] = 0x10325476; 00323 } 00324 00325 void 00326 md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes) 00327 { 00328 const md5_byte_t *p = data; 00329 int left = nbytes; 00330 int offset = (pms->count[0] >> 3) & 63; 00331 md5_word_t nbits = (md5_word_t)(nbytes << 3); 00332 00333 if (nbytes <= 0) 00334 return; 00335 00336 /* Update the message length. */ 00337 pms->count[1] += nbytes >> 29; 00338 pms->count[0] += nbits; 00339 if (pms->count[0] < nbits) 00340 pms->count[1]++; 00341 00342 /* Process an initial partial block. */ 00343 if (offset) { 00344 int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); 00345 00346 memcpy(pms->buf + offset, p, copy); 00347 if (offset + copy < 64) 00348 return; 00349 p += copy; 00350 left -= copy; 00351 md5_process(pms, pms->buf); 00352 } 00353 00354 /* Process full blocks. */ 00355 for (; left >= 64; p += 64, left -= 64) 00356 md5_process(pms, p); 00357 00358 /* Process a final partial block. */ 00359 if (left) 00360 memcpy(pms->buf, p, left); 00361 } 00362 00363 void 00364 md5_finish(md5_state_t *pms, md5_byte_t digest[16]) 00365 { 00366 static const md5_byte_t pad[64] = { 00367 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00368 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00369 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00370 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 00371 }; 00372 md5_byte_t data[8]; 00373 int i; 00374 00375 /* Save the length before padding. */ 00376 for (i = 0; i < 8; ++i) 00377 data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); 00378 /* Pad to 56 bytes mod 64. */ 00379 md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); 00380 /* Append the length. */ 00381 md5_append(pms, data, 8); 00382 for (i = 0; i < 16; ++i) 00383 digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); 00384 } 00385 #endif /* HAVE_SSL */