jsonpath scanner: reentrant scanner
[pgsql.git] / src / common / md5.c
blob32b696a66dfd8ff8d1268f02a0fdc6a129e123ed
1 /*-------------------------------------------------------------------------
3 * md5.c
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-2024, PostgreSQL Global Development Group
11 * Portions Copyright (c) 1994, Regents of the University of California
13 * IDENTIFICATION
14 * src/common/md5.c
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
27 * are met:
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
47 * SUCH DAMAGE.
50 #ifndef FRONTEND
51 #include "postgres.h"
52 #else
53 #include "postgres_fe.h"
54 #endif
56 #include "md5_int.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) \
66 do { \
67 (a) = (a) + F((b), (c), (d)) + X[(k)] + T[(i)]; \
68 (a) = SHIFT((a), (s)); \
69 (a) = (b) + (a); \
70 } while (0)
72 #define ROUND2(a, b, c, d, k, s, i) \
73 do { \
74 (a) = (a) + G((b), (c), (d)) + X[(k)] + T[(i)]; \
75 (a) = SHIFT((a), (s)); \
76 (a) = (b) + (a); \
77 } while (0)
79 #define ROUND3(a, b, c, d, k, s, i) \
80 do { \
81 (a) = (a) + H((b), (c), (d)) + X[(k)] + T[(i)]; \
82 (a) = SHIFT((a), (s)); \
83 (a) = (b) + (a); \
84 } while (0)
86 #define ROUND4(a, b, c, d, k, s, i) \
87 do { \
88 (a) = (a) + I((b), (c), (d)) + X[(k)] + T[(i)]; \
89 (a) = SHIFT((a), (s)); \
90 (a) = (b) + (a); \
91 } while (0)
93 #define Sa 7
94 #define Sb 12
95 #define Sc 17
96 #define Sd 22
98 #define Se 5
99 #define Sf 9
100 #define Sg 14
101 #define Sh 20
103 #define Si 4
104 #define Sj 11
105 #define Sk 16
106 #define Sl 23
108 #define Sm 6
109 #define Sn 10
110 #define So 15
111 #define Sp 21
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 static void
154 md5_calc(const uint8 *b64, pg_md5_ctx *ctx)
156 uint32 A = ctx->md5_sta;
157 uint32 B = ctx->md5_stb;
158 uint32 C = ctx->md5_stc;
159 uint32 D = ctx->md5_std;
161 #ifndef WORDS_BIGENDIAN
162 const uint32 *X = (const uint32 *) b64;
163 #else
164 /* 4 byte words */
165 /* what a brute force but fast! */
166 uint32 X[16];
167 uint8 *y = (uint8 *) X;
169 y[0] = b64[3];
170 y[1] = b64[2];
171 y[2] = b64[1];
172 y[3] = b64[0];
173 y[4] = b64[7];
174 y[5] = b64[6];
175 y[6] = b64[5];
176 y[7] = b64[4];
177 y[8] = b64[11];
178 y[9] = b64[10];
179 y[10] = b64[9];
180 y[11] = b64[8];
181 y[12] = b64[15];
182 y[13] = b64[14];
183 y[14] = b64[13];
184 y[15] = b64[12];
185 y[16] = b64[19];
186 y[17] = b64[18];
187 y[18] = b64[17];
188 y[19] = b64[16];
189 y[20] = b64[23];
190 y[21] = b64[22];
191 y[22] = b64[21];
192 y[23] = b64[20];
193 y[24] = b64[27];
194 y[25] = b64[26];
195 y[26] = b64[25];
196 y[27] = b64[24];
197 y[28] = b64[31];
198 y[29] = b64[30];
199 y[30] = b64[29];
200 y[31] = b64[28];
201 y[32] = b64[35];
202 y[33] = b64[34];
203 y[34] = b64[33];
204 y[35] = b64[32];
205 y[36] = b64[39];
206 y[37] = b64[38];
207 y[38] = b64[37];
208 y[39] = b64[36];
209 y[40] = b64[43];
210 y[41] = b64[42];
211 y[42] = b64[41];
212 y[43] = b64[40];
213 y[44] = b64[47];
214 y[45] = b64[46];
215 y[46] = b64[45];
216 y[47] = b64[44];
217 y[48] = b64[51];
218 y[49] = b64[50];
219 y[50] = b64[49];
220 y[51] = b64[48];
221 y[52] = b64[55];
222 y[53] = b64[54];
223 y[54] = b64[53];
224 y[55] = b64[52];
225 y[56] = b64[59];
226 y[57] = b64[58];
227 y[58] = b64[57];
228 y[59] = b64[56];
229 y[60] = b64[63];
230 y[61] = b64[62];
231 y[62] = b64[61];
232 y[63] = b64[60];
233 #endif
235 ROUND1(A, B, C, D, 0, Sa, 1);
236 ROUND1(D, A, B, C, 1, Sb, 2);
237 ROUND1(C, D, A, B, 2, Sc, 3);
238 ROUND1(B, C, D, A, 3, Sd, 4);
239 ROUND1(A, B, C, D, 4, Sa, 5);
240 ROUND1(D, A, B, C, 5, Sb, 6);
241 ROUND1(C, D, A, B, 6, Sc, 7);
242 ROUND1(B, C, D, A, 7, Sd, 8);
243 ROUND1(A, B, C, D, 8, Sa, 9);
244 ROUND1(D, A, B, C, 9, Sb, 10);
245 ROUND1(C, D, A, B, 10, Sc, 11);
246 ROUND1(B, C, D, A, 11, Sd, 12);
247 ROUND1(A, B, C, D, 12, Sa, 13);
248 ROUND1(D, A, B, C, 13, Sb, 14);
249 ROUND1(C, D, A, B, 14, Sc, 15);
250 ROUND1(B, C, D, A, 15, Sd, 16);
252 ROUND2(A, B, C, D, 1, Se, 17);
253 ROUND2(D, A, B, C, 6, Sf, 18);
254 ROUND2(C, D, A, B, 11, Sg, 19);
255 ROUND2(B, C, D, A, 0, Sh, 20);
256 ROUND2(A, B, C, D, 5, Se, 21);
257 ROUND2(D, A, B, C, 10, Sf, 22);
258 ROUND2(C, D, A, B, 15, Sg, 23);
259 ROUND2(B, C, D, A, 4, Sh, 24);
260 ROUND2(A, B, C, D, 9, Se, 25);
261 ROUND2(D, A, B, C, 14, Sf, 26);
262 ROUND2(C, D, A, B, 3, Sg, 27);
263 ROUND2(B, C, D, A, 8, Sh, 28);
264 ROUND2(A, B, C, D, 13, Se, 29);
265 ROUND2(D, A, B, C, 2, Sf, 30);
266 ROUND2(C, D, A, B, 7, Sg, 31);
267 ROUND2(B, C, D, A, 12, Sh, 32);
269 ROUND3(A, B, C, D, 5, Si, 33);
270 ROUND3(D, A, B, C, 8, Sj, 34);
271 ROUND3(C, D, A, B, 11, Sk, 35);
272 ROUND3(B, C, D, A, 14, Sl, 36);
273 ROUND3(A, B, C, D, 1, Si, 37);
274 ROUND3(D, A, B, C, 4, Sj, 38);
275 ROUND3(C, D, A, B, 7, Sk, 39);
276 ROUND3(B, C, D, A, 10, Sl, 40);
277 ROUND3(A, B, C, D, 13, Si, 41);
278 ROUND3(D, A, B, C, 0, Sj, 42);
279 ROUND3(C, D, A, B, 3, Sk, 43);
280 ROUND3(B, C, D, A, 6, Sl, 44);
281 ROUND3(A, B, C, D, 9, Si, 45);
282 ROUND3(D, A, B, C, 12, Sj, 46);
283 ROUND3(C, D, A, B, 15, Sk, 47);
284 ROUND3(B, C, D, A, 2, Sl, 48);
286 ROUND4(A, B, C, D, 0, Sm, 49);
287 ROUND4(D, A, B, C, 7, Sn, 50);
288 ROUND4(C, D, A, B, 14, So, 51);
289 ROUND4(B, C, D, A, 5, Sp, 52);
290 ROUND4(A, B, C, D, 12, Sm, 53);
291 ROUND4(D, A, B, C, 3, Sn, 54);
292 ROUND4(C, D, A, B, 10, So, 55);
293 ROUND4(B, C, D, A, 1, Sp, 56);
294 ROUND4(A, B, C, D, 8, Sm, 57);
295 ROUND4(D, A, B, C, 15, Sn, 58);
296 ROUND4(C, D, A, B, 6, So, 59);
297 ROUND4(B, C, D, A, 13, Sp, 60);
298 ROUND4(A, B, C, D, 4, Sm, 61);
299 ROUND4(D, A, B, C, 11, Sn, 62);
300 ROUND4(C, D, A, B, 2, So, 63);
301 ROUND4(B, C, D, A, 9, Sp, 64);
303 ctx->md5_sta += A;
304 ctx->md5_stb += B;
305 ctx->md5_stc += C;
306 ctx->md5_std += D;
309 static void
310 md5_pad(pg_md5_ctx *ctx)
312 unsigned int gap;
314 /* Don't count up padding. Keep md5_n. */
315 gap = MD5_BUFLEN - ctx->md5_i;
316 if (gap > 8)
318 memmove(ctx->md5_buf + ctx->md5_i, md5_paddat,
319 gap - sizeof(ctx->md5_n));
321 else
323 /* including gap == 8 */
324 memmove(ctx->md5_buf + ctx->md5_i, md5_paddat, gap);
325 md5_calc(ctx->md5_buf, ctx);
326 memmove(ctx->md5_buf, md5_paddat + gap,
327 MD5_BUFLEN - sizeof(ctx->md5_n));
330 /* 8 byte word */
331 #ifndef WORDS_BIGENDIAN
332 memmove(&ctx->md5_buf[56], &ctx->md5_n8[0], 8);
333 #else
334 ctx->md5_buf[56] = ctx->md5_n8[7];
335 ctx->md5_buf[57] = ctx->md5_n8[6];
336 ctx->md5_buf[58] = ctx->md5_n8[5];
337 ctx->md5_buf[59] = ctx->md5_n8[4];
338 ctx->md5_buf[60] = ctx->md5_n8[3];
339 ctx->md5_buf[61] = ctx->md5_n8[2];
340 ctx->md5_buf[62] = ctx->md5_n8[1];
341 ctx->md5_buf[63] = ctx->md5_n8[0];
342 #endif
344 md5_calc(ctx->md5_buf, ctx);
347 static void
348 md5_result(uint8 *digest, pg_md5_ctx *ctx)
350 /* 4 byte words */
351 #ifndef WORDS_BIGENDIAN
352 memmove(digest, &ctx->md5_st8[0], 16);
353 #else
354 digest[0] = ctx->md5_st8[3];
355 digest[1] = ctx->md5_st8[2];
356 digest[2] = ctx->md5_st8[1];
357 digest[3] = ctx->md5_st8[0];
358 digest[4] = ctx->md5_st8[7];
359 digest[5] = ctx->md5_st8[6];
360 digest[6] = ctx->md5_st8[5];
361 digest[7] = ctx->md5_st8[4];
362 digest[8] = ctx->md5_st8[11];
363 digest[9] = ctx->md5_st8[10];
364 digest[10] = ctx->md5_st8[9];
365 digest[11] = ctx->md5_st8[8];
366 digest[12] = ctx->md5_st8[15];
367 digest[13] = ctx->md5_st8[14];
368 digest[14] = ctx->md5_st8[13];
369 digest[15] = ctx->md5_st8[12];
370 #endif
374 /* External routines for this MD5 implementation */
377 * pg_md5_init
379 * Initialize a MD5 context.
381 void
382 pg_md5_init(pg_md5_ctx *ctx)
384 ctx->md5_n = 0;
385 ctx->md5_i = 0;
386 ctx->md5_sta = MD5_A0;
387 ctx->md5_stb = MD5_B0;
388 ctx->md5_stc = MD5_C0;
389 ctx->md5_std = MD5_D0;
390 memset(ctx->md5_buf, 0, sizeof(ctx->md5_buf));
395 * pg_md5_update
397 * Update a MD5 context.
399 void
400 pg_md5_update(pg_md5_ctx *ctx, const uint8 *data, size_t len)
402 unsigned int gap,
405 ctx->md5_n += len * 8; /* byte to bit */
406 gap = MD5_BUFLEN - ctx->md5_i;
408 if (len >= gap)
410 memmove(ctx->md5_buf + ctx->md5_i, data, gap);
411 md5_calc(ctx->md5_buf, ctx);
413 for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN)
414 md5_calc(data + i, ctx);
416 ctx->md5_i = len - i;
417 memmove(ctx->md5_buf, data + i, ctx->md5_i);
419 else
421 memmove(ctx->md5_buf + ctx->md5_i, data, len);
422 ctx->md5_i += len;
427 * pg_md5_final
429 * Finalize a MD5 context.
431 void
432 pg_md5_final(pg_md5_ctx *ctx, uint8 *dest)
434 md5_pad(ctx);
435 md5_result(dest, ctx);