2 * This is work is derived from material Copyright RSA Data Security, Inc.
4 * The RSA copyright statement and Licence for that original material is
5 * included below. This is followed by the Apache copyright statement and
6 * licence for the modifications made to that material.
9 /* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
12 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
15 License to copy and use this software is granted provided that it
16 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
17 Algorithm" in all material mentioning or referencing this software
20 License is also granted to make and use derivative works provided
21 that such works are identified as "derived from the RSA Data
22 Security, Inc. MD5 Message-Digest Algorithm" in all material
23 mentioning or referencing the derived work.
25 RSA Data Security, Inc. makes no representations concerning either
26 the merchantability of this software or the suitability of this
27 software for any particular purpose. It is provided "as is"
28 without express or implied warranty of any kind.
30 These notices must be retained in any copies of any part of this
31 documentation and/or software.
34 /* Licensed to the Apache Software Foundation (ASF) under one or more
35 * contributor license agreements. See the NOTICE file distributed with
36 * this work for additional information regarding copyright ownership.
37 * The ASF licenses this file to You under the Apache License, Version 2.0
38 * (the "License"); you may not use this file except in compliance with
39 * the License. You may obtain a copy of the License at
41 * http://www.apache.org/licenses/LICENSE-2.0
43 * Unless required by applicable law or agreed to in writing, software
44 * distributed under the License is distributed on an "AS IS" BASIS,
45 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
46 * See the License for the specific language governing permissions and
47 * limitations under the License.
51 * The apr_md5_encode() routine uses much code obtained from the FreeBSD 3.0
52 * MD5 crypt() function, which is licenced as follows:
53 * ----------------------------------------------------------------------------
54 * "THE BEER-WARE LICENSE" (Revision 42):
55 * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
56 * can do whatever you want with this stuff. If we meet some day, and you think
57 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
58 * ----------------------------------------------------------------------------
62 * pseudo_md5.c: md5-esque hash sum calculation for short data blocks.
63 * Code taken and adapted from the APR (see licenses above).
65 #include "private/svn_pseudo_md5.h"
67 /* Constants for MD5 calculation.
87 /* F, G, H and I are basic MD5 functions.
89 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
90 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
91 #define H(x, y, z) ((x) ^ (y) ^ (z))
92 #define I(x, y, z) ((y) ^ ((x) | (~z)))
94 /* ROTATE_LEFT rotates x left n bits.
96 #if defined(_MSC_VER) && _MSC_VER >= 1310
97 #pragma intrinsic(_rotl)
98 #define ROTATE_LEFT(x, n) (_rotl(x,n))
100 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
103 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
104 * Rotation is separate from addition to prevent recomputation.
106 #define FF(a, b, c, d, x, s, ac) { \
107 (a) += F ((b), (c), (d)) + (x) + (apr_uint32_t)(ac); \
108 (a) = ROTATE_LEFT ((a), (s)); \
111 #define GG(a, b, c, d, x, s, ac) { \
112 (a) += G ((b), (c), (d)) + (x) + (apr_uint32_t)(ac); \
113 (a) = ROTATE_LEFT ((a), (s)); \
116 #define HH(a, b, c, d, x, s, ac) { \
117 (a) += H ((b), (c), (d)) + (x) + (apr_uint32_t)(ac); \
118 (a) = ROTATE_LEFT ((a), (s)); \
121 #define II(a, b, c, d, x, s, ac) { \
122 (a) += I ((b), (c), (d)) + (x) + (apr_uint32_t)(ac); \
123 (a) = ROTATE_LEFT ((a), (s)); \
127 /* The idea of the functions below is as follows:
129 * - The core MD5 algorithm does not assume that the "important" data
130 * is at the begin of the encryption block, followed by e.g. 0.
131 * Instead, all bits are equally relevant.
133 * - If some bytes in the input are known to be 0, we may hard-code them.
134 * With the previous property, it is safe to move them to the upper end
135 * of the encryption block to maximize the number of steps that can be
138 * - Variable-length streams will use the upper 8 byte of the last
139 * encryption block to store the stream length in bits (to make 0, 00,
140 * 000, ... etc. produce different hash sums).
142 * - We will hash at most 63 bytes, i.e. 504 bits. In the standard stream
143 * implementation, the upper 6 bytes of the last encryption block would
144 * be 0. We will put at least one non-NULL value in the last 4 bytes.
145 * Therefore, our input will always be different to a standard MD5 stream
146 * implementation in either block count, content or both.
148 * - Our length indicator also varies with the number bytes in the input.
149 * Hence, different pseudo-MD5 input length produces different output
150 * (with "cryptographic probability") even if the content is all 0 or
151 * otherwise identical.
153 * - Collisions between pseudo-MD5 and pseudo-MD5 as well as pseudo-MD5
154 * and standard MD5 are as likely as any other MD5 collision.
157 void svn__pseudo_md5_15(apr_uint32_t digest[4],
158 const apr_uint32_t x[4])
160 apr_uint32_t a = 0x67452301;
161 apr_uint32_t b = 0xefcdab89;
162 apr_uint32_t c = 0x98badcfe;
163 apr_uint32_t d = 0x10325476;
165 /* make sure byte 63 gets the marker independently of BE / LE */
166 apr_uint32_t x3n = x[3] ^ 0xffffffff;
169 FF(a, b, c, d, 0, S11, 0xd76aa478); /* 1 */
170 FF(d, a, b, c, 0, S12, 0xe8c7b756); /* 2 */
171 FF(c, d, a, b, 0, S13, 0x242070db); /* 3 */
172 FF(b, c, d, a, 0, S14, 0xc1bdceee); /* 4 */
173 FF(a, b, c, d, 0, S11, 0xf57c0faf); /* 5 */
174 FF(d, a, b, c, 0, S12, 0x4787c62a); /* 6 */
175 FF(c, d, a, b, 0, S13, 0xa8304613); /* 7 */
176 FF(b, c, d, a, 0, S14, 0xfd469501); /* 8 */
177 FF(a, b, c, d, 0, S11, 0x698098d8); /* 9 */
178 FF(d, a, b, c, 0, S12, 0x8b44f7af); /* 10 */
179 FF(c, d, a, b, 0, S13, 0xffff5bb1); /* 11 */
180 FF(b, c, d, a, 0, S14, 0x895cd7be); /* 12 */
181 FF(a, b, c, d, x[0], S11, 0x6b901122); /* 13 */
182 FF(d, a, b, c, x[1], S12, 0xfd987193); /* 14 */
183 FF(c, d, a, b, x[2], S13, 0xa679438e); /* 15 */
184 FF(b, c, d, a, x3n, S14, 0x49b40821); /* 16 */
187 GG(a, b, c, d, 0, S21, 0xf61e2562); /* 17 */
188 GG(d, a, b, c, 0, S22, 0xc040b340); /* 18 */
189 GG(c, d, a, b, 0, S23, 0x265e5a51); /* 19 */
190 GG(b, c, d, a, 0, S24, 0xe9b6c7aa); /* 20 */
191 GG(a, b, c, d, 0, S21, 0xd62f105d); /* 21 */
192 GG(d, a, b, c, 0, S22, 0x2441453); /* 22 */
193 GG(c, d, a, b, x3n, S23, 0xd8a1e681); /* 23 */
194 GG(b, c, d, a, 0, S24, 0xe7d3fbc8); /* 24 */
195 GG(a, b, c, d, 0, S21, 0x21e1cde6); /* 25 */
196 GG(d, a, b, c, x[2], S22, 0xc33707d6); /* 26 */
197 GG(c, d, a, b, 0, S23, 0xf4d50d87); /* 27 */
198 GG(b, c, d, a, 0, S24, 0x455a14ed); /* 28 */
199 GG(a, b, c, d, x[1], S21, 0xa9e3e905); /* 29 */
200 GG(d, a, b, c, 0, S22, 0xfcefa3f8); /* 30 */
201 GG(c, d, a, b, 0, S23, 0x676f02d9); /* 31 */
202 GG(b, c, d, a, x[0], S24, 0x8d2a4c8a); /* 32 */
205 HH(a, b, c, d, 0, S31, 0xfffa3942); /* 33 */
206 HH(d, a, b, c, 0, S32, 0x8771f681); /* 34 */
207 HH(c, d, a, b, 0, S33, 0x6d9d6122); /* 35 */
208 HH(b, c, d, a, x[2], S34, 0xfde5380c); /* 36 */
209 HH(a, b, c, d, 0, S31, 0xa4beea44); /* 37 */
210 HH(d, a, b, c, 0, S32, 0x4bdecfa9); /* 38 */
211 HH(c, d, a, b, 0, S33, 0xf6bb4b60); /* 39 */
212 HH(b, c, d, a, 0, S34, 0xbebfbc70); /* 40 */
213 HH(a, b, c, d, x[1], S31, 0x289b7ec6); /* 41 */
214 HH(d, a, b, c, 0, S32, 0xeaa127fa); /* 42 */
215 HH(c, d, a, b, 0, S33, 0xd4ef3085); /* 43 */
216 HH(b, c, d, a, 0, S34, 0x4881d05); /* 44 */
217 HH(a, b, c, d, 0, S31, 0xd9d4d039); /* 45 */
218 HH(d, a, b, c, x[0], S32, 0xe6db99e5); /* 46 */
219 HH(c, d, a, b, x3n, S33, 0x1fa27cf8); /* 47 */
220 HH(b, c, d, a, 0, S34, 0xc4ac5665); /* 48 */
223 II(a, b, c, d, 0, S41, 0xf4292244); /* 49 */
224 II(d, a, b, c, 0, S42, 0x432aff97); /* 50 */
225 II(c, d, a, b, x[2], S43, 0xab9423a7); /* 51 */
226 II(b, c, d, a, 0, S44, 0xfc93a039); /* 52 */
227 II(a, b, c, d, x[0], S41, 0x655b59c3); /* 53 */
228 II(d, a, b, c, 0, S42, 0x8f0ccc92); /* 54 */
229 II(c, d, a, b, 0, S43, 0xffeff47d); /* 55 */
230 II(b, c, d, a, 0, S44, 0x85845dd1); /* 56 */
231 II(a, b, c, d, 0, S41, 0x6fa87e4f); /* 57 */
232 II(d, a, b, c, x3n, S42, 0xfe2ce6e0); /* 58 */
233 II(c, d, a, b, 0, S43, 0xa3014314); /* 59 */
234 II(b, c, d, a, x[1], S44, 0x4e0811a1); /* 60 */
235 II(a, b, c, d, 0, S41, 0xf7537e82); /* 61 */
236 II(d, a, b, c, 0, S42, 0xbd3af235); /* 62 */
237 II(c, d, a, b, 0, S43, 0x2ad7d2bb); /* 63 */
238 II(b, c, d, a, 0, S44, 0xeb86d391); /* 64 */
246 void svn__pseudo_md5_31(apr_uint32_t digest[4],
247 const apr_uint32_t x[8])
249 apr_uint32_t a = 0x67452301;
250 apr_uint32_t b = 0xefcdab89;
251 apr_uint32_t c = 0x98badcfe;
252 apr_uint32_t d = 0x10325476;
254 /* make sure byte 63 gets the marker independently of BE / LE */
255 apr_uint32_t x7n = x[7] ^ 0xfefefefe;
258 FF(a, b, c, d, 0, S11, 0xd76aa478); /* 1 */
259 FF(d, a, b, c, 0, S12, 0xe8c7b756); /* 2 */
260 FF(c, d, a, b, 0, S13, 0x242070db); /* 3 */
261 FF(b, c, d, a, 0, S14, 0xc1bdceee); /* 4 */
262 FF(a, b, c, d, 0, S11, 0xf57c0faf); /* 5 */
263 FF(d, a, b, c, 0, S12, 0x4787c62a); /* 6 */
264 FF(c, d, a, b, 0, S13, 0xa8304613); /* 7 */
265 FF(b, c, d, a, 0, S14, 0xfd469501); /* 8 */
266 FF(a, b, c, d, x[0], S11, 0x698098d8); /* 9 */
267 FF(d, a, b, c, x[1], S12, 0x8b44f7af); /* 10 */
268 FF(c, d, a, b, x[2], S13, 0xffff5bb1); /* 11 */
269 FF(b, c, d, a, x[3], S14, 0x895cd7be); /* 12 */
270 FF(a, b, c, d, x[4], S11, 0x6b901122); /* 13 */
271 FF(d, a, b, c, x[5], S12, 0xfd987193); /* 14 */
272 FF(c, d, a, b, x[6], S13, 0xa679438e); /* 15 */
273 FF(b, c, d, a, x7n, S14, 0x49b40821); /* 16 */
276 GG(a, b, c, d, 0, S21, 0xf61e2562); /* 17 */
277 GG(d, a, b, c, 0, S22, 0xc040b340); /* 18 */
278 GG(c, d, a, b, x[3], S23, 0x265e5a51); /* 19 */
279 GG(b, c, d, a, 0, S24, 0xe9b6c7aa); /* 20 */
280 GG(a, b, c, d, 0, S21, 0xd62f105d); /* 21 */
281 GG(d, a, b, c, x[2], S22, 0x2441453); /* 22 */
282 GG(c, d, a, b, x7n, S23, 0xd8a1e681); /* 23 */
283 GG(b, c, d, a, 0, S24, 0xe7d3fbc8); /* 24 */
284 GG(a, b, c, d, x[1], S21, 0x21e1cde6); /* 25 */
285 GG(d, a, b, c, x[6], S22, 0xc33707d6); /* 26 */
286 GG(c, d, a, b, 0, S23, 0xf4d50d87); /* 27 */
287 GG(b, c, d, a, x[0], S24, 0x455a14ed); /* 28 */
288 GG(a, b, c, d, x[5], S21, 0xa9e3e905); /* 29 */
289 GG(d, a, b, c, 0, S22, 0xfcefa3f8); /* 30 */
290 GG(c, d, a, b, 0, S23, 0x676f02d9); /* 31 */
291 GG(b, c, d, a, x[4], S24, 0x8d2a4c8a); /* 32 */
294 HH(a, b, c, d, 0, S31, 0xfffa3942); /* 33 */
295 HH(d, a, b, c, x[0], S32, 0x8771f681); /* 34 */
296 HH(c, d, a, b, x[3], S33, 0x6d9d6122); /* 35 */
297 HH(b, c, d, a, x[6], S34, 0xfde5380c); /* 36 */
298 HH(a, b, c, d, 0, S31, 0xa4beea44); /* 37 */
299 HH(d, a, b, c, 0, S32, 0x4bdecfa9); /* 38 */
300 HH(c, d, a, b, 0, S33, 0xf6bb4b60); /* 39 */
301 HH(b, c, d, a, x[2], S34, 0xbebfbc70); /* 40 */
302 HH(a, b, c, d, x[5], S31, 0x289b7ec6); /* 41 */
303 HH(d, a, b, c, 0, S32, 0xeaa127fa); /* 42 */
304 HH(c, d, a, b, 0, S33, 0xd4ef3085); /* 43 */
305 HH(b, c, d, a, 0, S34, 0x4881d05); /* 44 */
306 HH(a, b, c, d, x[1], S31, 0xd9d4d039); /* 45 */
307 HH(d, a, b, c, x[4], S32, 0xe6db99e5); /* 46 */
308 HH(c, d, a, b, x7n, S33, 0x1fa27cf8); /* 47 */
309 HH(b, c, d, a, 0, S34, 0xc4ac5665); /* 48 */
312 II(a, b, c, d, 0, S41, 0xf4292244); /* 49 */
313 II(d, a, b, c, 0, S42, 0x432aff97); /* 50 */
314 II(c, d, a, b, x[6], S43, 0xab9423a7); /* 51 */
315 II(b, c, d, a, 0, S44, 0xfc93a039); /* 52 */
316 II(a, b, c, d, x[4], S41, 0x655b59c3); /* 53 */
317 II(d, a, b, c, 0, S42, 0x8f0ccc92); /* 54 */
318 II(c, d, a, b, x[2], S43, 0xffeff47d); /* 55 */
319 II(b, c, d, a, 0, S44, 0x85845dd1); /* 56 */
320 II(a, b, c, d, x[0], S41, 0x6fa87e4f); /* 57 */
321 II(d, a, b, c, x7n, S42, 0xfe2ce6e0); /* 58 */
322 II(c, d, a, b, 0, S43, 0xa3014314); /* 59 */
323 II(b, c, d, a, x[5], S44, 0x4e0811a1); /* 60 */
324 II(a, b, c, d, 0, S41, 0xf7537e82); /* 61 */
325 II(d, a, b, c, x[3], S42, 0xbd3af235); /* 62 */
326 II(c, d, a, b, 0, S43, 0x2ad7d2bb); /* 63 */
327 II(b, c, d, a, x[1], S44, 0xeb86d391); /* 64 */
335 void svn__pseudo_md5_63(apr_uint32_t digest[4],
336 const apr_uint32_t x[16])
338 apr_uint32_t a = 0x67452301;
339 apr_uint32_t b = 0xefcdab89;
340 apr_uint32_t c = 0x98badcfe;
341 apr_uint32_t d = 0x10325476;
343 /* make sure byte 63 gets the marker independently of BE / LE */
344 apr_uint32_t x15n = x[15] ^ 0xfcfcfcfc;
347 FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */
348 FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */
349 FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */
350 FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */
351 FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */
352 FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */
353 FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */
354 FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */
355 FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */
356 FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */
357 FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
358 FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
359 FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
360 FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
361 FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
362 FF(b, c, d, a, x15n, S14, 0x49b40821); /* 16 */
365 GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */
366 GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */
367 GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
368 GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */
369 GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */
370 GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
371 GG(c, d, a, b, x15n, S23, 0xd8a1e681); /* 23 */
372 GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */
373 GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */
374 GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
375 GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */
376 GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */
377 GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
378 GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */
379 GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */
380 GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
383 HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */
384 HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */
385 HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
386 HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
387 HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */
388 HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */
389 HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */
390 HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
391 HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
392 HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */
393 HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */
394 HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */
395 HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */
396 HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
397 HH(c, d, a, b, x15n, S33, 0x1fa27cf8); /* 47 */
398 HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */
401 II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */
402 II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */
403 II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
404 II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */
405 II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
406 II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */
407 II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
408 II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */
409 II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */
410 II(d, a, b, c, x15n, S42, 0xfe2ce6e0); /* 58 */
411 II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */
412 II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
413 II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */
414 II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
415 II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */
416 II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */