1 /* 2 ** SQLite uses this code for testing only. It is not a part of 3 ** the SQLite library. This file implements two new TCL commands 4 ** "md5" and "md5file" that compute md5 checksums on arbitrary text 5 ** and on complete files. These commands are used by the "testfixture" 6 ** program to help verify the correct operation of the SQLite library. 7 ** 8 ** The original use of these TCL commands was to test the ROLLBACK 9 ** feature of SQLite. First compute the MD5-checksum of the database. 10 ** Then make some changes but rollback the changes rather than commit 11 ** them. Compute a second MD5-checksum of the file and verify that the 12 ** two checksums are the same. Such is the original use of this code. 13 ** New uses may have been added since this comment was written. 14 */ 15 /* 16 * This code implements the MD5 message-digest algorithm. 17 * The algorithm is due to Ron Rivest. This code was 18 * written by Colin Plumb in 1993, no copyright is claimed. 19 * This code is in the public domain; do with it what you wish. 20 * 21 * Equivalent code is available from RSA Data Security, Inc. 22 * This code has been tested against that, and is equivalent, 23 * except that you don't need to include two pages of legalese 24 * with every copy. 25 * 26 * To compute the message digest of a chunk of bytes, declare an 27 * MD5Context structure, pass it to MD5Init, call MD5Update as 28 * needed on buffers full of bytes, and then call MD5Final, which 29 * will fill a supplied 16-byte array with the digest. 30 */ 31 #include <tcl.h> 32 #include <string.h> 33 #include "sqlite.h" 34 35 /* 36 * If compiled on a machine that doesn't have a 32-bit integer, 37 * you just set "uint32" to the appropriate datatype for an 38 * unsigned 32-bit integer. For example: 39 * 40 * cc -Duint32='unsigned long' md5.c 41 * 42 */ 43 #ifndef uint32 44 # define uint32 unsigned int 45 #endif 46 47 struct Context { 48 uint32 buf[4]; 49 uint32 bits[2]; 50 unsigned char in[64]; 51 }; 52 typedef char MD5Context[88]; 53 54 /* 55 * Note: this code is harmless on little-endian machines. 56 */ 57 static void byteReverse (unsigned char *buf, unsigned longs){ 58 uint32 t; 59 do { 60 t = (uint32)((unsigned)buf[3]<<8 | buf[2]) << 16 | 61 ((unsigned)buf[1]<<8 | buf[0]); 62 *(uint32 *)buf = t; 63 buf += 4; 64 } while (--longs); 65 } 66 /* The four core functions - F1 is optimized somewhat */ 67 68 /* #define F1(x, y, z) (x & y | ~x & z) */ 69 #define F1(x, y, z) (z ^ (x & (y ^ z))) 70 #define F2(x, y, z) F1(z, x, y) 71 #define F3(x, y, z) (x ^ y ^ z) 72 #define F4(x, y, z) (y ^ (x | ~z)) 73 74 /* This is the central step in the MD5 algorithm. */ 75 #define MD5STEP(f, w, x, y, z, data, s) \ 76 ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x ) 77 78 /* 79 * The core of the MD5 algorithm, this alters an existing MD5 hash to 80 * reflect the addition of 16 longwords of new data. MD5Update blocks 81 * the data and converts bytes into longwords for this routine. 82 */ 83 static void MD5Transform(uint32 buf[4], const uint32 in[16]){ 84 register uint32 a, b, c, d; 85 86 a = buf[0]; 87 b = buf[1]; 88 c = buf[2]; 89 d = buf[3]; 90 91 MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478, 7); 92 MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12); 93 MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17); 94 MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22); 95 MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf, 7); 96 MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12); 97 MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17); 98 MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22); 99 MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8, 7); 100 MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12); 101 MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17); 102 MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22); 103 MD5STEP(F1, a, b, c, d, in[12]+0x6b901122, 7); 104 MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12); 105 MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17); 106 MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22); 107 108 MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562, 5); 109 MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340, 9); 110 MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14); 111 MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20); 112 MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d, 5); 113 MD5STEP(F2, d, a, b, c, in[10]+0x02441453, 9); 114 MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14); 115 MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20); 116 MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6, 5); 117 MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6, 9); 118 MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14); 119 MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20); 120 MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905, 5); 121 MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8, 9); 122 MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14); 123 MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20); 124 125 MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942, 4); 126 MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11); 127 MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16); 128 MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23); 129 MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44, 4); 130 MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11); 131 MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16); 132 MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23); 133 MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6, 4); 134 MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11); 135 MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16); 136 MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23); 137 MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039, 4); 138 MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11); 139 MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16); 140 MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23); 141 142 MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244, 6); 143 MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10); 144 MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15); 145 MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21); 146 MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3, 6); 147 MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10); 148 MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15); 149 MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21); 150 MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f, 6); 151 MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10); 152 MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15); 153 MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21); 154 MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82, 6); 155 MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10); 156 MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15); 157 MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21); 158 159 buf[0] += a; 160 buf[1] += b; 161 buf[2] += c; 162 buf[3] += d; 163 } 164 165 /* 166 * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious 167 * initialization constants. 168 */ 169 static void MD5Init(MD5Context *pCtx){ 170 struct Context *ctx = (struct Context *)pCtx; 171 ctx->buf[0] = 0x67452301; 172 ctx->buf[1] = 0xefcdab89; 173 ctx->buf[2] = 0x98badcfe; 174 ctx->buf[3] = 0x10325476; 175 ctx->bits[0] = 0; 176 ctx->bits[1] = 0; 177 } 178 179 /* 180 * Update context to reflect the concatenation of another buffer full 181 * of bytes. 182 */ 183 static 184 void MD5Update(MD5Context *pCtx, const unsigned char *buf, unsigned int len){ 185 struct Context *ctx = (struct Context *)pCtx; 186 uint32 t; 187 188 /* Update bitcount */ 189 190 t = ctx->bits[0]; 191 if ((ctx->bits[0] = t + ((uint32)len << 3)) < t) 192 ctx->bits[1]++; /* Carry from low to high */ 193 ctx->bits[1] += len >> 29; 194 195 t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ 196 197 /* Handle any leading odd-sized chunks */ 198 199 if ( t ) { 200 unsigned char *p = (unsigned char *)ctx->in + t; 201 202 t = 64-t; 203 if (len < t) { 204 memcpy(p, buf, len); 205 return; 206 } 207 memcpy(p, buf, t); 208 byteReverse(ctx->in, 16); 209 MD5Transform(ctx->buf, (uint32 *)ctx->in); 210 buf += t; 211 len -= t; 212 } 213 214 /* Process data in 64-byte chunks */ 215 216 while (len >= 64) { 217 memcpy(ctx->in, buf, 64); 218 byteReverse(ctx->in, 16); 219 MD5Transform(ctx->buf, (uint32 *)ctx->in); 220 buf += 64; 221 len -= 64; 222 } 223 224 /* Handle any remaining bytes of data. */ 225 226 memcpy(ctx->in, buf, len); 227 } 228 229 /* 230 * Final wrapup - pad to 64-byte boundary with the bit pattern 231 * 1 0* (64-bit count of bits processed, MSB-first) 232 */ 233 static void MD5Final(unsigned char digest[16], MD5Context *pCtx){ 234 struct Context *ctx = (struct Context *)pCtx; 235 unsigned count; 236 unsigned char *p; 237 238 /* Compute number of bytes mod 64 */ 239 count = (ctx->bits[0] >> 3) & 0x3F; 240 241 /* Set the first char of padding to 0x80. This is safe since there is 242 always at least one byte free */ 243 p = ctx->in + count; 244 *p++ = 0x80; 245 246 /* Bytes of padding needed to make 64 bytes */ 247 count = 64 - 1 - count; 248 249 /* Pad out to 56 mod 64 */ 250 if (count < 8) { 251 /* Two lots of padding: Pad the first block to 64 bytes */ 252 memset(p, 0, count); 253 byteReverse(ctx->in, 16); 254 MD5Transform(ctx->buf, (uint32 *)ctx->in); 255 256 /* Now fill the next block with 56 bytes */ 257 memset(ctx->in, 0, 56); 258 } else { 259 /* Pad block to 56 bytes */ 260 memset(p, 0, count-8); 261 } 262 byteReverse(ctx->in, 14); 263 264 /* Append length in bits and transform */ 265 ((uint32 *)ctx->in)[ 14 ] = ctx->bits[0]; 266 ((uint32 *)ctx->in)[ 15 ] = ctx->bits[1]; 267 268 MD5Transform(ctx->buf, (uint32 *)ctx->in); 269 byteReverse((unsigned char *)ctx->buf, 4); 270 memcpy(digest, ctx->buf, 16); 271 memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ 272 } 273 274 /* 275 ** Convert a digest into base-16. digest should be declared as 276 ** "unsigned char digest[16]" in the calling function. The MD5 277 ** digest is stored in the first 16 bytes. zBuf should 278 ** be "char zBuf[33]". 279 */ 280 static void DigestToBase16(unsigned char *digest, char *zBuf){ 281 static char const zEncode[] = "0123456789abcdef"; 282 int i, j; 283 284 for(j=i=0; i<16; i++){ 285 int a = digest[i]; 286 zBuf[j++] = zEncode[(a>>4)&0xf]; 287 zBuf[j++] = zEncode[a & 0xf]; 288 } 289 zBuf[j] = 0; 290 } 291 292 /* 293 ** A TCL command for md5. The argument is the text to be hashed. The 294 ** Result is the hash in base64. 295 */ 296 static int md5_cmd(void*cd, Tcl_Interp *interp, int argc, const char **argv){ 297 MD5Context ctx; 298 unsigned char digest[16]; 299 300 if( argc!=2 ){ 301 Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], 302 " TEXT\"", 0); 303 return TCL_ERROR; 304 } 305 MD5Init(&ctx); 306 MD5Update(&ctx, (unsigned char*)argv[1], (unsigned)strlen(argv[1])); 307 MD5Final(digest, &ctx); 308 DigestToBase16(digest, interp->result); 309 return TCL_OK; 310 } 311 312 /* 313 ** A TCL command to take the md5 hash of a file. The argument is the 314 ** name of the file. 315 */ 316 static int md5file_cmd(void*cd, Tcl_Interp*interp, int argc, const char **argv){ 317 FILE *in; 318 MD5Context ctx; 319 unsigned char digest[16]; 320 char zBuf[10240]; 321 322 if( argc!=2 ){ 323 Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], 324 " FILENAME\"", 0); 325 return TCL_ERROR; 326 } 327 in = fopen(argv[1],"rb"); 328 if( in==0 ){ 329 Tcl_AppendResult(interp,"unable to open file \"", argv[1], 330 "\" for reading", 0); 331 return TCL_ERROR; 332 } 333 MD5Init(&ctx); 334 for(;;){ 335 int n; 336 n = fread(zBuf, 1, sizeof(zBuf), in); 337 if( n<=0 ) break; 338 MD5Update(&ctx, (unsigned char*)zBuf, (unsigned)n); 339 } 340 fclose(in); 341 MD5Final(digest, &ctx); 342 DigestToBase16(digest, interp->result); 343 return TCL_OK; 344 } 345 346 /* 347 ** Register the two TCL commands above with the TCL interpreter. 348 */ 349 int Md5_Init(Tcl_Interp *interp){ 350 Tcl_CreateCommand(interp, "md5", (Tcl_CmdProc*)md5_cmd, 0, 0); 351 Tcl_CreateCommand(interp, "md5file", (Tcl_CmdProc*)md5file_cmd, 0, 0); 352 return TCL_OK; 353 } 354 355 /* 356 ** During testing, the special md5sum() aggregate function is available. 357 ** inside SQLite. The following routines implement that function. 358 */ 359 static void md5step(sqlite_func *context, int argc, const char **argv){ 360 MD5Context *p; 361 int i; 362 if( argc<1 ) return; 363 p = sqlite_aggregate_context(context, sizeof(*p)); 364 if( p==0 ) return; 365 if( sqlite_aggregate_count(context)==1 ){ 366 MD5Init(p); 367 } 368 for(i=0; i<argc; i++){ 369 if( argv[i] ){ 370 MD5Update(p, (unsigned char*)argv[i], strlen(argv[i])); 371 } 372 } 373 } 374 static void md5finalize(sqlite_func *context){ 375 MD5Context *p; 376 unsigned char digest[16]; 377 char zBuf[33]; 378 p = sqlite_aggregate_context(context, sizeof(*p)); 379 MD5Final(digest,p); 380 DigestToBase16(digest, zBuf); 381 sqlite_set_result_string(context, zBuf, strlen(zBuf)); 382 } 383 void Md5_Register(sqlite *db){ 384 sqlite_create_aggregate(db, "md5sum", -1, md5step, md5finalize, 0); 385 } 386