1 /*-------------------------------------------------------------------------
4 * Implements the MD5 Message-Digest Algorithm
6 * Fallback implementation of MD5, as specified in RFC 1321. This
7 * implementation is a simple one, in that it needs every input byte
8 * to be buffered before doing any calculations.
10 * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
11 * Portions Copyright (c) 1994, Regents of the University of California
16 *-------------------------------------------------------------------------
19 /* $KAME: md5.c,v 1.3 2000/02/22 14:01:17 itojun Exp $ */
22 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
23 * All rights reserved.
25 * Redistribution and use in source and binary forms, with or without
26 * modification, are permitted provided that the following conditions
28 * 1. Redistributions of source code must retain the above copyright
29 * notice, this list of conditions and the following disclaimer.
30 * 2. Redistributions in binary form must reproduce the above copyright
31 * notice, this list of conditions and the following disclaimer in the
32 * documentation and/or other materials provided with the distribution.
33 * 3. Neither the name of the project nor the names of its contributors
34 * may be used to endorse or promote products derived from this software
35 * without specific prior written permission.
37 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
38 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
40 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
41 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
42 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
43 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
45 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
46 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53 #include "postgres_fe.h"
58 #define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s))))
60 #define F(X, Y, Z) (((X) & (Y)) | ((~X) & (Z)))
61 #define G(X, Y, Z) (((X) & (Z)) | ((Y) & (~Z)))
62 #define H(X, Y, Z) ((X) ^ (Y) ^ (Z))
63 #define I(X, Y, Z) ((Y) ^ ((X) | (~Z)))
65 #define ROUND1(a, b, c, d, k, s, i) \
67 (a) = (a) + F((b), (c), (d)) + X[(k)] + T[(i)]; \
68 (a) = SHIFT((a), (s)); \
72 #define ROUND2(a, b, c, d, k, s, i) \
74 (a) = (a) + G((b), (c), (d)) + X[(k)] + T[(i)]; \
75 (a) = SHIFT((a), (s)); \
79 #define ROUND3(a, b, c, d, k, s, i) \
81 (a) = (a) + H((b), (c), (d)) + X[(k)] + T[(i)]; \
82 (a) = SHIFT((a), (s)); \
86 #define ROUND4(a, b, c, d, k, s, i) \
88 (a) = (a) + I((b), (c), (d)) + X[(k)] + T[(i)]; \
89 (a) = SHIFT((a), (s)); \
113 #define MD5_A0 0x67452301
114 #define MD5_B0 0xefcdab89
115 #define MD5_C0 0x98badcfe
116 #define MD5_D0 0x10325476
118 /* Integer part of 4294967296 times abs(sin(i)), where i is in radians. */
119 static const uint32 T
[65] = {
121 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
122 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
123 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
124 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
126 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
127 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8,
128 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
129 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
131 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
132 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
133 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
134 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
136 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
137 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
138 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
139 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
142 static const uint8 md5_paddat
[MD5_BUFLEN
] = {
143 0x80, 0, 0, 0, 0, 0, 0, 0,
144 0, 0, 0, 0, 0, 0, 0, 0,
145 0, 0, 0, 0, 0, 0, 0, 0,
146 0, 0, 0, 0, 0, 0, 0, 0,
147 0, 0, 0, 0, 0, 0, 0, 0,
148 0, 0, 0, 0, 0, 0, 0, 0,
149 0, 0, 0, 0, 0, 0, 0, 0,
150 0, 0, 0, 0, 0, 0, 0, 0,
153 #ifdef WORDS_BIGENDIAN
158 md5_calc(const uint8
*b64
, pg_md5_ctx
*ctx
)
160 uint32 A
= ctx
->md5_sta
;
161 uint32 B
= ctx
->md5_stb
;
162 uint32 C
= ctx
->md5_stc
;
163 uint32 D
= ctx
->md5_std
;
165 #ifndef WORDS_BIGENDIAN
166 const uint32
*X
= (const uint32
*) b64
;
169 /* what a brute force but fast! */
170 uint8
*y
= (uint8
*) X
;
238 ROUND1(A
, B
, C
, D
, 0, Sa
, 1);
239 ROUND1(D
, A
, B
, C
, 1, Sb
, 2);
240 ROUND1(C
, D
, A
, B
, 2, Sc
, 3);
241 ROUND1(B
, C
, D
, A
, 3, Sd
, 4);
242 ROUND1(A
, B
, C
, D
, 4, Sa
, 5);
243 ROUND1(D
, A
, B
, C
, 5, Sb
, 6);
244 ROUND1(C
, D
, A
, B
, 6, Sc
, 7);
245 ROUND1(B
, C
, D
, A
, 7, Sd
, 8);
246 ROUND1(A
, B
, C
, D
, 8, Sa
, 9);
247 ROUND1(D
, A
, B
, C
, 9, Sb
, 10);
248 ROUND1(C
, D
, A
, B
, 10, Sc
, 11);
249 ROUND1(B
, C
, D
, A
, 11, Sd
, 12);
250 ROUND1(A
, B
, C
, D
, 12, Sa
, 13);
251 ROUND1(D
, A
, B
, C
, 13, Sb
, 14);
252 ROUND1(C
, D
, A
, B
, 14, Sc
, 15);
253 ROUND1(B
, C
, D
, A
, 15, Sd
, 16);
255 ROUND2(A
, B
, C
, D
, 1, Se
, 17);
256 ROUND2(D
, A
, B
, C
, 6, Sf
, 18);
257 ROUND2(C
, D
, A
, B
, 11, Sg
, 19);
258 ROUND2(B
, C
, D
, A
, 0, Sh
, 20);
259 ROUND2(A
, B
, C
, D
, 5, Se
, 21);
260 ROUND2(D
, A
, B
, C
, 10, Sf
, 22);
261 ROUND2(C
, D
, A
, B
, 15, Sg
, 23);
262 ROUND2(B
, C
, D
, A
, 4, Sh
, 24);
263 ROUND2(A
, B
, C
, D
, 9, Se
, 25);
264 ROUND2(D
, A
, B
, C
, 14, Sf
, 26);
265 ROUND2(C
, D
, A
, B
, 3, Sg
, 27);
266 ROUND2(B
, C
, D
, A
, 8, Sh
, 28);
267 ROUND2(A
, B
, C
, D
, 13, Se
, 29);
268 ROUND2(D
, A
, B
, C
, 2, Sf
, 30);
269 ROUND2(C
, D
, A
, B
, 7, Sg
, 31);
270 ROUND2(B
, C
, D
, A
, 12, Sh
, 32);
272 ROUND3(A
, B
, C
, D
, 5, Si
, 33);
273 ROUND3(D
, A
, B
, C
, 8, Sj
, 34);
274 ROUND3(C
, D
, A
, B
, 11, Sk
, 35);
275 ROUND3(B
, C
, D
, A
, 14, Sl
, 36);
276 ROUND3(A
, B
, C
, D
, 1, Si
, 37);
277 ROUND3(D
, A
, B
, C
, 4, Sj
, 38);
278 ROUND3(C
, D
, A
, B
, 7, Sk
, 39);
279 ROUND3(B
, C
, D
, A
, 10, Sl
, 40);
280 ROUND3(A
, B
, C
, D
, 13, Si
, 41);
281 ROUND3(D
, A
, B
, C
, 0, Sj
, 42);
282 ROUND3(C
, D
, A
, B
, 3, Sk
, 43);
283 ROUND3(B
, C
, D
, A
, 6, Sl
, 44);
284 ROUND3(A
, B
, C
, D
, 9, Si
, 45);
285 ROUND3(D
, A
, B
, C
, 12, Sj
, 46);
286 ROUND3(C
, D
, A
, B
, 15, Sk
, 47);
287 ROUND3(B
, C
, D
, A
, 2, Sl
, 48);
289 ROUND4(A
, B
, C
, D
, 0, Sm
, 49);
290 ROUND4(D
, A
, B
, C
, 7, Sn
, 50);
291 ROUND4(C
, D
, A
, B
, 14, So
, 51);
292 ROUND4(B
, C
, D
, A
, 5, Sp
, 52);
293 ROUND4(A
, B
, C
, D
, 12, Sm
, 53);
294 ROUND4(D
, A
, B
, C
, 3, Sn
, 54);
295 ROUND4(C
, D
, A
, B
, 10, So
, 55);
296 ROUND4(B
, C
, D
, A
, 1, Sp
, 56);
297 ROUND4(A
, B
, C
, D
, 8, Sm
, 57);
298 ROUND4(D
, A
, B
, C
, 15, Sn
, 58);
299 ROUND4(C
, D
, A
, B
, 6, So
, 59);
300 ROUND4(B
, C
, D
, A
, 13, Sp
, 60);
301 ROUND4(A
, B
, C
, D
, 4, Sm
, 61);
302 ROUND4(D
, A
, B
, C
, 11, Sn
, 62);
303 ROUND4(C
, D
, A
, B
, 2, So
, 63);
304 ROUND4(B
, C
, D
, A
, 9, Sp
, 64);
313 md5_pad(pg_md5_ctx
*ctx
)
317 /* Don't count up padding. Keep md5_n. */
318 gap
= MD5_BUFLEN
- ctx
->md5_i
;
321 memmove(ctx
->md5_buf
+ ctx
->md5_i
, md5_paddat
,
322 gap
- sizeof(ctx
->md5_n
));
326 /* including gap == 8 */
327 memmove(ctx
->md5_buf
+ ctx
->md5_i
, md5_paddat
, gap
);
328 md5_calc(ctx
->md5_buf
, ctx
);
329 memmove(ctx
->md5_buf
, md5_paddat
+ gap
,
330 MD5_BUFLEN
- sizeof(ctx
->md5_n
));
334 #ifndef WORDS_BIGENDIAN
335 memmove(&ctx
->md5_buf
[56], &ctx
->md5_n8
[0], 8);
337 ctx
->md5_buf
[56] = ctx
->md5_n8
[7];
338 ctx
->md5_buf
[57] = ctx
->md5_n8
[6];
339 ctx
->md5_buf
[58] = ctx
->md5_n8
[5];
340 ctx
->md5_buf
[59] = ctx
->md5_n8
[4];
341 ctx
->md5_buf
[60] = ctx
->md5_n8
[3];
342 ctx
->md5_buf
[61] = ctx
->md5_n8
[2];
343 ctx
->md5_buf
[62] = ctx
->md5_n8
[1];
344 ctx
->md5_buf
[63] = ctx
->md5_n8
[0];
347 md5_calc(ctx
->md5_buf
, ctx
);
351 md5_result(uint8
*digest
, pg_md5_ctx
*ctx
)
354 #ifndef WORDS_BIGENDIAN
355 memmove(digest
, &ctx
->md5_st8
[0], 16);
357 digest
[0] = ctx
->md5_st8
[3];
358 digest
[1] = ctx
->md5_st8
[2];
359 digest
[2] = ctx
->md5_st8
[1];
360 digest
[3] = ctx
->md5_st8
[0];
361 digest
[4] = ctx
->md5_st8
[7];
362 digest
[5] = ctx
->md5_st8
[6];
363 digest
[6] = ctx
->md5_st8
[5];
364 digest
[7] = ctx
->md5_st8
[4];
365 digest
[8] = ctx
->md5_st8
[11];
366 digest
[9] = ctx
->md5_st8
[10];
367 digest
[10] = ctx
->md5_st8
[9];
368 digest
[11] = ctx
->md5_st8
[8];
369 digest
[12] = ctx
->md5_st8
[15];
370 digest
[13] = ctx
->md5_st8
[14];
371 digest
[14] = ctx
->md5_st8
[13];
372 digest
[15] = ctx
->md5_st8
[12];
377 /* External routines for this MD5 implementation */
382 * Initialize a MD5 context.
385 pg_md5_init(pg_md5_ctx
*ctx
)
389 ctx
->md5_sta
= MD5_A0
;
390 ctx
->md5_stb
= MD5_B0
;
391 ctx
->md5_stc
= MD5_C0
;
392 ctx
->md5_std
= MD5_D0
;
393 memset(ctx
->md5_buf
, 0, sizeof(ctx
->md5_buf
));
400 * Update a MD5 context.
403 pg_md5_update(pg_md5_ctx
*ctx
, const uint8
*data
, size_t len
)
408 ctx
->md5_n
+= len
* 8; /* byte to bit */
409 gap
= MD5_BUFLEN
- ctx
->md5_i
;
413 memmove(ctx
->md5_buf
+ ctx
->md5_i
, data
, gap
);
414 md5_calc(ctx
->md5_buf
, ctx
);
416 for (i
= gap
; i
+ MD5_BUFLEN
<= len
; i
+= MD5_BUFLEN
)
417 md5_calc(data
+ i
, ctx
);
419 ctx
->md5_i
= len
- i
;
420 memmove(ctx
->md5_buf
, data
+ i
, ctx
->md5_i
);
424 memmove(ctx
->md5_buf
+ ctx
->md5_i
, data
, len
);
432 * Finalize a MD5 context.
435 pg_md5_final(pg_md5_ctx
*ctx
, uint8
*dest
)
438 md5_result(dest
, ctx
);