openModeller
Version 1.4.0
|
00001 /* 00002 * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. 00003 * MD5 Message-Digest Algorithm (RFC 1321). 00004 * 00005 * Homepage: 00006 * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 00007 * 00008 * Author: 00009 * Alexander Peslyak, better known as Solar Designer <solar at openwall.com> 00010 * 00011 * This software was written by Alexander Peslyak in 2001. No copyright is 00012 * claimed, and the software is hereby placed in the public domain. 00013 * In case this attempt to disclaim copyright and place the software in the 00014 * public domain is deemed null and void, then the software is 00015 * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the 00016 * general public under the following terms: 00017 * 00018 * Redistribution and use in source and binary forms, with or without 00019 * modification, are permitted. 00020 * 00021 * There's ABSOLUTELY NO WARRANTY, express or implied. 00022 * 00023 * (This is a heavily cut-down "BSD license".) 00024 * 00025 * This differs from Colin Plumb's older public domain implementation in that 00026 * no exactly 32-bit integer data type is required (any 32-bit or wider 00027 * unsigned integer data type will do), there's no compile-time endianness 00028 * configuration, and the function prototypes match OpenSSL's. No code from 00029 * Colin Plumb's implementation has been reused; this comment merely compares 00030 * the properties of the two independent implementations. 00031 * 00032 * The primary goals of this implementation are portability and ease of use. 00033 * It is meant to be fast, but not as fast as possible. Some known 00034 * optimizations are not included to reduce source code size and avoid 00035 * compile-time configuration. 00036 */ 00037 00038 #ifndef HAVE_OPENSSL 00039 00040 #include <string.h> 00041 00042 #include "md5.h" 00043 00044 /* 00045 * The basic MD5 functions. 00046 * 00047 * F and G are optimized compared to their RFC 1321 definitions for 00048 * architectures that lack an AND-NOT instruction, just like in Colin Plumb's 00049 * implementation. 00050 */ 00051 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) 00052 #define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) 00053 #define H(x, y, z) ((x) ^ (y) ^ (z)) 00054 #define I(x, y, z) ((y) ^ ((x) | ~(z))) 00055 00056 /* 00057 * The MD5 transformation for all four rounds. 00058 */ 00059 #define STEP(f, a, b, c, d, x, t, s) \ 00060 (a) += f((b), (c), (d)) + (x) + (t); \ 00061 (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ 00062 (a) += (b); 00063 00064 /* 00065 * SET reads 4 input bytes in little-endian byte order and stores them 00066 * in a properly aligned word in host byte order. 00067 * 00068 * The check for little-endian architectures that tolerate unaligned 00069 * memory accesses is just an optimization. Nothing will break if it 00070 * doesn't work. 00071 */ 00072 #if defined(__i386__) || defined(__x86_64__) || defined(__vax__) 00073 #define SET(n) \ 00074 (*(MD5_u32plus *)&ptr[(n) * 4]) 00075 #define GET(n) \ 00076 SET(n) 00077 #else 00078 #define SET(n) \ 00079 (ctx->block[(n)] = \ 00080 (MD5_u32plus)ptr[(n) * 4] | \ 00081 ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \ 00082 ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \ 00083 ((MD5_u32plus)ptr[(n) * 4 + 3] << 24)) 00084 #define GET(n) \ 00085 (ctx->block[(n)]) 00086 #endif 00087 00088 /* 00089 * This processes one or more 64-byte data blocks, but does NOT update 00090 * the bit counters. There are no alignment requirements. 00091 */ 00092 static void *body(MD5_CTX *ctx, void *data, unsigned long size) 00093 { 00094 unsigned char *ptr; 00095 MD5_u32plus a, b, c, d; 00096 MD5_u32plus saved_a, saved_b, saved_c, saved_d; 00097 00098 ptr = data; 00099 00100 a = ctx->a; 00101 b = ctx->b; 00102 c = ctx->c; 00103 d = ctx->d; 00104 00105 do { 00106 saved_a = a; 00107 saved_b = b; 00108 saved_c = c; 00109 saved_d = d; 00110 00111 /* Round 1 */ 00112 STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7) 00113 STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12) 00114 STEP(F, c, d, a, b, SET(2), 0x242070db, 17) 00115 STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22) 00116 STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7) 00117 STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12) 00118 STEP(F, c, d, a, b, SET(6), 0xa8304613, 17) 00119 STEP(F, b, c, d, a, SET(7), 0xfd469501, 22) 00120 STEP(F, a, b, c, d, SET(8), 0x698098d8, 7) 00121 STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12) 00122 STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17) 00123 STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22) 00124 STEP(F, a, b, c, d, SET(12), 0x6b901122, 7) 00125 STEP(F, d, a, b, c, SET(13), 0xfd987193, 12) 00126 STEP(F, c, d, a, b, SET(14), 0xa679438e, 17) 00127 STEP(F, b, c, d, a, SET(15), 0x49b40821, 22) 00128 00129 /* Round 2 */ 00130 STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5) 00131 STEP(G, d, a, b, c, GET(6), 0xc040b340, 9) 00132 STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14) 00133 STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20) 00134 STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5) 00135 STEP(G, d, a, b, c, GET(10), 0x02441453, 9) 00136 STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14) 00137 STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20) 00138 STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5) 00139 STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) 00140 STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) 00141 STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) 00142 STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) 00143 STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) 00144 STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) 00145 STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) 00146 00147 /* Round 3 */ 00148 STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) 00149 STEP(H, d, a, b, c, GET(8), 0x8771f681, 11) 00150 STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) 00151 STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23) 00152 STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) 00153 STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11) 00154 STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) 00155 STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23) 00156 STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) 00157 STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11) 00158 STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) 00159 STEP(H, b, c, d, a, GET(6), 0x04881d05, 23) 00160 STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) 00161 STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11) 00162 STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) 00163 STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23) 00164 00165 /* Round 4 */ 00166 STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) 00167 STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) 00168 STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) 00169 STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) 00170 STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) 00171 STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) 00172 STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) 00173 STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) 00174 STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6) 00175 STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10) 00176 STEP(I, c, d, a, b, GET(6), 0xa3014314, 15) 00177 STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21) 00178 STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6) 00179 STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10) 00180 STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15) 00181 STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21) 00182 00183 a += saved_a; 00184 b += saved_b; 00185 c += saved_c; 00186 d += saved_d; 00187 00188 ptr += 64; 00189 } while (size -= 64); 00190 00191 ctx->a = a; 00192 ctx->b = b; 00193 ctx->c = c; 00194 ctx->d = d; 00195 00196 return ptr; 00197 } 00198 00199 void MD5_Init(MD5_CTX *ctx) 00200 { 00201 ctx->a = 0x67452301; 00202 ctx->b = 0xefcdab89; 00203 ctx->c = 0x98badcfe; 00204 ctx->d = 0x10325476; 00205 00206 ctx->lo = 0; 00207 ctx->hi = 0; 00208 } 00209 00210 void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size) 00211 { 00212 MD5_u32plus saved_lo; 00213 unsigned long used, free; 00214 00215 saved_lo = ctx->lo; 00216 if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) 00217 ctx->hi++; 00218 ctx->hi += size >> 29; 00219 00220 used = saved_lo & 0x3f; 00221 00222 if (used) { 00223 free = 64 - used; 00224 00225 if (size < free) { 00226 memcpy(&ctx->buffer[used], data, size); 00227 return; 00228 } 00229 00230 memcpy(&ctx->buffer[used], data, free); 00231 data = (unsigned char *)data + free; 00232 size -= free; 00233 body(ctx, ctx->buffer, 64); 00234 } 00235 00236 if (size >= 64) { 00237 data = body(ctx, data, size & ~(unsigned long)0x3f); 00238 size &= 0x3f; 00239 } 00240 00241 memcpy(ctx->buffer, data, size); 00242 } 00243 00244 void MD5_Final(unsigned char *result, MD5_CTX *ctx) 00245 { 00246 unsigned long used, free; 00247 00248 used = ctx->lo & 0x3f; 00249 00250 ctx->buffer[used++] = 0x80; 00251 00252 free = 64 - used; 00253 00254 if (free < 8) { 00255 memset(&ctx->buffer[used], 0, free); 00256 body(ctx, ctx->buffer, 64); 00257 used = 0; 00258 free = 64; 00259 } 00260 00261 memset(&ctx->buffer[used], 0, free - 8); 00262 00263 ctx->lo <<= 3; 00264 ctx->buffer[56] = ctx->lo; 00265 ctx->buffer[57] = ctx->lo >> 8; 00266 ctx->buffer[58] = ctx->lo >> 16; 00267 ctx->buffer[59] = ctx->lo >> 24; 00268 ctx->buffer[60] = ctx->hi; 00269 ctx->buffer[61] = ctx->hi >> 8; 00270 ctx->buffer[62] = ctx->hi >> 16; 00271 ctx->buffer[63] = ctx->hi >> 24; 00272 00273 body(ctx, ctx->buffer, 64); 00274 00275 result[0] = ctx->a; 00276 result[1] = ctx->a >> 8; 00277 result[2] = ctx->a >> 16; 00278 result[3] = ctx->a >> 24; 00279 result[4] = ctx->b; 00280 result[5] = ctx->b >> 8; 00281 result[6] = ctx->b >> 16; 00282 result[7] = ctx->b >> 24; 00283 result[8] = ctx->c; 00284 result[9] = ctx->c >> 8; 00285 result[10] = ctx->c >> 16; 00286 result[11] = ctx->c >> 24; 00287 result[12] = ctx->d; 00288 result[13] = ctx->d >> 8; 00289 result[14] = ctx->d >> 16; 00290 result[15] = ctx->d >> 24; 00291 00292 memset(ctx, 0, sizeof(*ctx)); 00293 } 00294 00295 #endif 00296