2 * SQLite uses this code for testing only. It is not a part of the SQLite
3 * library. This file implements two new TCL commands "md5" and "md5file" that
4 * compute md5 checksums on arbitrary text and on complete files. These
5 * commands are used by the "testfixture" program to help verify the correct
6 * operation of the SQLite library.
8 * The original use of these TCL commands was to test the ROLLBACK feature of
9 * SQLite. First compute the MD5-checksum of the database. Then make some
10 * changes but rollback the changes rather than commit them. Compute a second
11 * MD5-checksum of the file and verify that the two checksums are the same.
12 * Such is the original use of this code. New uses may have been added since
13 * this comment was written.
18 * This code implements the MD5 message-digest algorithm. The algorithm is due
19 * to Ron Rivest. This code was written by Colin Plumb in 1993, no copyright is
20 * claimed. This code is in the public domain; do with it what you wish.
22 * Equivalent code is available from RSA Data Security, Inc. This code has been
23 * tested against that, and is equivalent, except that you don't need to
24 * include two pages of legalese with every copy.
26 * To compute the message digest of a chunk of bytes, declare an MD5Context
27 * structure, pass it to MD5Init, call MD5Update as needed on buffers full of
28 * bytes, and then call MD5Final, which will fill a supplied 16-byte array with
36 * If compiled on a machine that doesn't have a 32-bit integer, you just set
37 * "uint32" to the appropriate datatype for an unsigned 32-bit integer. For
40 * cc -Duint32='unsigned long' md5.c
44 # define uint32 unsigned int
52 typedef char MD5Context
[88];
55 * Note: this code is harmless on little-endian machines.
57 static void byteReverse (unsigned char *buf
, unsigned longs
)
61 t
= (uint32
)((unsigned)buf
[3]<<8 | buf
[2]) << 16 |
62 ((unsigned)buf
[1]<<8 | buf
[0]);
67 /* The four core functions - F1 is optimized somewhat */
69 /* #define F1(x, y, z) (x & y | ~x & z) */
70 #define F1(x, y, z) (z ^ (x & (y ^ z)))
71 #define F2(x, y, z) F1(z, x, y)
72 #define F3(x, y, z) (x ^ y ^ z)
73 #define F4(x, y, z) (y ^ (x | ~z))
75 /* This is the central step in the MD5 algorithm. */
76 #define MD5STEP(f, w, x, y, z, data, s) \
77 ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
80 * The core of the MD5 algorithm, this alters an existing MD5 hash to
81 * reflect the addition of 16 longwords of new data. MD5Update blocks
82 * the data and converts bytes into longwords for this routine.
84 static void MD5Transform(uint32 buf
[4], const uint32 in
[16])
86 register uint32 a
, b
, c
, d
;
93 MD5STEP(F1
, a
, b
, c
, d
, in
[ 0]+0xd76aa478, 7);
94 MD5STEP(F1
, d
, a
, b
, c
, in
[ 1]+0xe8c7b756, 12);
95 MD5STEP(F1
, c
, d
, a
, b
, in
[ 2]+0x242070db, 17);
96 MD5STEP(F1
, b
, c
, d
, a
, in
[ 3]+0xc1bdceee, 22);
97 MD5STEP(F1
, a
, b
, c
, d
, in
[ 4]+0xf57c0faf, 7);
98 MD5STEP(F1
, d
, a
, b
, c
, in
[ 5]+0x4787c62a, 12);
99 MD5STEP(F1
, c
, d
, a
, b
, in
[ 6]+0xa8304613, 17);
100 MD5STEP(F1
, b
, c
, d
, a
, in
[ 7]+0xfd469501, 22);
101 MD5STEP(F1
, a
, b
, c
, d
, in
[ 8]+0x698098d8, 7);
102 MD5STEP(F1
, d
, a
, b
, c
, in
[ 9]+0x8b44f7af, 12);
103 MD5STEP(F1
, c
, d
, a
, b
, in
[10]+0xffff5bb1, 17);
104 MD5STEP(F1
, b
, c
, d
, a
, in
[11]+0x895cd7be, 22);
105 MD5STEP(F1
, a
, b
, c
, d
, in
[12]+0x6b901122, 7);
106 MD5STEP(F1
, d
, a
, b
, c
, in
[13]+0xfd987193, 12);
107 MD5STEP(F1
, c
, d
, a
, b
, in
[14]+0xa679438e, 17);
108 MD5STEP(F1
, b
, c
, d
, a
, in
[15]+0x49b40821, 22);
110 MD5STEP(F2
, a
, b
, c
, d
, in
[ 1]+0xf61e2562, 5);
111 MD5STEP(F2
, d
, a
, b
, c
, in
[ 6]+0xc040b340, 9);
112 MD5STEP(F2
, c
, d
, a
, b
, in
[11]+0x265e5a51, 14);
113 MD5STEP(F2
, b
, c
, d
, a
, in
[ 0]+0xe9b6c7aa, 20);
114 MD5STEP(F2
, a
, b
, c
, d
, in
[ 5]+0xd62f105d, 5);
115 MD5STEP(F2
, d
, a
, b
, c
, in
[10]+0x02441453, 9);
116 MD5STEP(F2
, c
, d
, a
, b
, in
[15]+0xd8a1e681, 14);
117 MD5STEP(F2
, b
, c
, d
, a
, in
[ 4]+0xe7d3fbc8, 20);
118 MD5STEP(F2
, a
, b
, c
, d
, in
[ 9]+0x21e1cde6, 5);
119 MD5STEP(F2
, d
, a
, b
, c
, in
[14]+0xc33707d6, 9);
120 MD5STEP(F2
, c
, d
, a
, b
, in
[ 3]+0xf4d50d87, 14);
121 MD5STEP(F2
, b
, c
, d
, a
, in
[ 8]+0x455a14ed, 20);
122 MD5STEP(F2
, a
, b
, c
, d
, in
[13]+0xa9e3e905, 5);
123 MD5STEP(F2
, d
, a
, b
, c
, in
[ 2]+0xfcefa3f8, 9);
124 MD5STEP(F2
, c
, d
, a
, b
, in
[ 7]+0x676f02d9, 14);
125 MD5STEP(F2
, b
, c
, d
, a
, in
[12]+0x8d2a4c8a, 20);
127 MD5STEP(F3
, a
, b
, c
, d
, in
[ 5]+0xfffa3942, 4);
128 MD5STEP(F3
, d
, a
, b
, c
, in
[ 8]+0x8771f681, 11);
129 MD5STEP(F3
, c
, d
, a
, b
, in
[11]+0x6d9d6122, 16);
130 MD5STEP(F3
, b
, c
, d
, a
, in
[14]+0xfde5380c, 23);
131 MD5STEP(F3
, a
, b
, c
, d
, in
[ 1]+0xa4beea44, 4);
132 MD5STEP(F3
, d
, a
, b
, c
, in
[ 4]+0x4bdecfa9, 11);
133 MD5STEP(F3
, c
, d
, a
, b
, in
[ 7]+0xf6bb4b60, 16);
134 MD5STEP(F3
, b
, c
, d
, a
, in
[10]+0xbebfbc70, 23);
135 MD5STEP(F3
, a
, b
, c
, d
, in
[13]+0x289b7ec6, 4);
136 MD5STEP(F3
, d
, a
, b
, c
, in
[ 0]+0xeaa127fa, 11);
137 MD5STEP(F3
, c
, d
, a
, b
, in
[ 3]+0xd4ef3085, 16);
138 MD5STEP(F3
, b
, c
, d
, a
, in
[ 6]+0x04881d05, 23);
139 MD5STEP(F3
, a
, b
, c
, d
, in
[ 9]+0xd9d4d039, 4);
140 MD5STEP(F3
, d
, a
, b
, c
, in
[12]+0xe6db99e5, 11);
141 MD5STEP(F3
, c
, d
, a
, b
, in
[15]+0x1fa27cf8, 16);
142 MD5STEP(F3
, b
, c
, d
, a
, in
[ 2]+0xc4ac5665, 23);
144 MD5STEP(F4
, a
, b
, c
, d
, in
[ 0]+0xf4292244, 6);
145 MD5STEP(F4
, d
, a
, b
, c
, in
[ 7]+0x432aff97, 10);
146 MD5STEP(F4
, c
, d
, a
, b
, in
[14]+0xab9423a7, 15);
147 MD5STEP(F4
, b
, c
, d
, a
, in
[ 5]+0xfc93a039, 21);
148 MD5STEP(F4
, a
, b
, c
, d
, in
[12]+0x655b59c3, 6);
149 MD5STEP(F4
, d
, a
, b
, c
, in
[ 3]+0x8f0ccc92, 10);
150 MD5STEP(F4
, c
, d
, a
, b
, in
[10]+0xffeff47d, 15);
151 MD5STEP(F4
, b
, c
, d
, a
, in
[ 1]+0x85845dd1, 21);
152 MD5STEP(F4
, a
, b
, c
, d
, in
[ 8]+0x6fa87e4f, 6);
153 MD5STEP(F4
, d
, a
, b
, c
, in
[15]+0xfe2ce6e0, 10);
154 MD5STEP(F4
, c
, d
, a
, b
, in
[ 6]+0xa3014314, 15);
155 MD5STEP(F4
, b
, c
, d
, a
, in
[13]+0x4e0811a1, 21);
156 MD5STEP(F4
, a
, b
, c
, d
, in
[ 4]+0xf7537e82, 6);
157 MD5STEP(F4
, d
, a
, b
, c
, in
[11]+0xbd3af235, 10);
158 MD5STEP(F4
, c
, d
, a
, b
, in
[ 2]+0x2ad7d2bb, 15);
159 MD5STEP(F4
, b
, c
, d
, a
, in
[ 9]+0xeb86d391, 21);
169 * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
170 * initialization constants.
172 static void MD5Init(MD5Context
*pCtx
)
174 struct Context
*ctx
= (struct Context
*)pCtx
;
175 ctx
->buf
[0] = 0x67452301;
176 ctx
->buf
[1] = 0xefcdab89;
177 ctx
->buf
[2] = 0x98badcfe;
178 ctx
->buf
[3] = 0x10325476;
185 * Update context to reflect the concatenation of another buffer full of bytes.
188 void MD5Update(MD5Context
*pCtx
, const unsigned char *buf
, unsigned int len
)
190 struct Context
*ctx
= (struct Context
*)pCtx
;
193 /* Update bitcount */
196 if ((ctx
->bits
[0] = t
+ ((uint32
)len
<< 3)) < t
)
197 ctx
->bits
[1]++; /* Carry from low to high */
198 ctx
->bits
[1] += len
>> 29;
200 t
= (t
>> 3) & 0x3f; /* Bytes already in shsInfo->data */
202 /* Handle any leading odd-sized chunks */
206 unsigned char *p
= (unsigned char *)ctx
->in
+ t
;
215 byteReverse(ctx
->in
, 16);
216 MD5Transform(ctx
->buf
, (uint32
*)ctx
->in
);
221 /* Process data in 64-byte chunks */
225 memcpy(ctx
->in
, buf
, 64);
226 byteReverse(ctx
->in
, 16);
227 MD5Transform(ctx
->buf
, (uint32
*)ctx
->in
);
232 /* Handle any remaining bytes of data. */
233 memcpy(ctx
->in
, buf
, len
);
238 * Final wrapup - pad to 64-byte boundary with the bit pattern 1 0* (64-bit
239 * count of bits processed, MSB-first)
241 static void MD5Final(unsigned char digest
[16], MD5Context
*pCtx
)
243 struct Context
*ctx
= (struct Context
*)pCtx
;
247 /* Compute number of bytes mod 64 */
248 count
= (ctx
->bits
[0] >> 3) & 0x3F;
251 * Set the first char of padding to 0x80. This is safe since there is
252 * always at least one byte free.
257 /* Bytes of padding needed to make 64 bytes */
258 count
= 64 - 1 - count
;
260 /* Pad out to 56 mod 64 */
263 /* Two lots of padding: Pad the first block to 64 bytes */
265 byteReverse(ctx
->in
, 16);
266 MD5Transform(ctx
->buf
, (uint32
*)ctx
->in
);
268 /* Now fill the next block with 56 bytes */
269 memset(ctx
->in
, 0, 56);
271 /* Pad block to 56 bytes */
272 memset(p
, 0, count
-8);
274 byteReverse(ctx
->in
, 14);
276 /* Append length in bits and transform */
277 ((uint32
*)ctx
->in
)[ 14 ] = ctx
->bits
[0];
278 ((uint32
*)ctx
->in
)[ 15 ] = ctx
->bits
[1];
280 MD5Transform(ctx
->buf
, (uint32
*)ctx
->in
);
281 byteReverse((unsigned char *)ctx
->buf
, 4);
282 memcpy(digest
, ctx
->buf
, 16);
283 memset(ctx
, 0, sizeof(ctx
)); /* In case it's sensitive */
288 * Convert a digest into base-16. digest should be declared as "unsigned char
289 * digest[16]" in the calling function. The MD5 digest is stored in the first
290 * 16 bytes. zBuf should be "char zBuf[33]".
292 static void DigestToBase16(unsigned char *digest
, char *zBuf
)
294 static char const zEncode
[] = "0123456789abcdef";
297 for( j
=i
=0; i
<16; i
++ )
300 zBuf
[j
++] = zEncode
[(a
>>4)&0xf];
301 zBuf
[j
++] = zEncode
[a
& 0xf];
308 * A TCL command for md5. The argument is the text to be hashed. The Result is
309 * the hash in base64.
311 static int md5_cmd(void*cd
, Tcl_Interp
*interp
, int argc
, const char **argv
)
314 unsigned char digest
[16];
318 Tcl_AppendResult(interp
,"wrong # args: should be \"", argv
[0],
323 MD5Update(&ctx
, (unsigned char*)argv
[1], (unsigned)strlen(argv
[1]));
324 MD5Final(digest
, &ctx
);
325 DigestToBase16(digest
, interp
->result
);
331 * A TCL command to take the md5 hash of a file. The argument is the name of
334 static int md5file_cmd(void*cd
, Tcl_Interp
*interp
, int argc
, const char **argv
)
338 unsigned char digest
[16];
343 Tcl_AppendResult(interp
,"wrong # args: should be \"", argv
[0],
347 in
= fopen(argv
[1],"rb");
350 Tcl_AppendResult(interp
,"unable to open file \"", argv
[1],
351 "\" for reading", 0);
358 n
= fread(zBuf
, 1, sizeof(zBuf
), in
);
360 MD5Update(&ctx
, (unsigned char*)zBuf
, (unsigned)n
);
363 MD5Final(digest
, &ctx
);
364 DigestToBase16(digest
, interp
->result
);
370 * Register the two TCL commands above with the TCL interpreter.
372 int Md5_Init(Tcl_Interp
*interp
)
374 Tcl_CreateCommand(interp
, "md5", (Tcl_CmdProc
*)md5_cmd
, 0, 0);
375 Tcl_CreateCommand(interp
, "md5file", (Tcl_CmdProc
*)md5file_cmd
, 0, 0);
381 * During testing, the special md5sum() aggregate function is available.
382 * inside SQLite. The following routines implement that function.
384 static void md5step(sqlite3_context
*context
, int argc
, sqlite3_value
**argv
)
389 p
= sqlite3_aggregate_context(context
, sizeof(*p
));
391 if( sqlite3_aggregate_count(context
)==1 )
393 for(i
=0; i
<argc
; i
++)
395 const char *zData
= sqlite3_value_text(argv
[i
]);
397 MD5Update(p
, zData
, strlen(zData
));
400 static void md5finalize(sqlite3_context
*context
)
403 unsigned char digest
[16];
405 p
= sqlite3_aggregate_context(context
, sizeof(*p
));
407 DigestToBase16(digest
, zBuf
);
408 sqlite3_result_text(context
, zBuf
, -1, SQLITE_TRANSIENT
);
410 void Md5_Register(sqlite3
*db
)
412 sqlite3_create_function(db
, "md5sum", -1, SQLITE_UTF8
, 0, 0,
413 md5step
, md5finalize
);