PostgreSQL Source Code  git master
md5.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * md5.c
4  * Implements the MD5 Message-Digest Algorithm
5  *
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.
9  *
10  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
11  * Portions Copyright (c) 1994, Regents of the University of California
12  *
13  * IDENTIFICATION
14  * src/common/md5.c
15  *
16  *-------------------------------------------------------------------------
17  */
18 
19 /* $KAME: md5.c,v 1.3 2000/02/22 14:01:17 itojun Exp $ */
20 
21 /*
22  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
23  * All rights reserved.
24  *
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.
36  *
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.
48  */
49 
50 #ifndef FRONTEND
51 #include "postgres.h"
52 #else
53 #include "postgres_fe.h"
54 #endif
55 
56 #include "md5_int.h"
57 
58 #define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s))))
59 
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)))
64 
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)
71 
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)
78 
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)
85 
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)
92 
93 #define Sa 7
94 #define Sb 12
95 #define Sc 17
96 #define Sd 22
97 
98 #define Se 5
99 #define Sf 9
100 #define Sg 14
101 #define Sh 20
102 
103 #define Si 4
104 #define Sj 11
105 #define Sk 16
106 #define Sl 23
107 
108 #define Sm 6
109 #define Sn 10
110 #define So 15
111 #define Sp 21
112 
113 #define MD5_A0 0x67452301
114 #define MD5_B0 0xefcdab89
115 #define MD5_C0 0x98badcfe
116 #define MD5_D0 0x10325476
117 
118 /* Integer part of 4294967296 times abs(sin(i)), where i is in radians. */
119 static const uint32 T[65] = {
120  0,
121  0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
122  0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
123  0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
124  0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
125 
126  0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
127  0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8,
128  0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
129  0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
130 
131  0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
132  0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
133  0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
134  0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
135 
136  0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
137  0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
138  0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
139  0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
140 };
141 
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,
151 };
152 
153 #ifdef WORDS_BIGENDIAN
154 static uint32 X[16];
155 #endif
156 
157 static void
158 md5_calc(const uint8 *b64, pg_md5_ctx *ctx)
159 {
160  uint32 A = ctx->md5_sta;
161  uint32 B = ctx->md5_stb;
162  uint32 C = ctx->md5_stc;
163  uint32 D = ctx->md5_std;
164 
165 #ifndef WORDS_BIGENDIAN
166  const uint32 *X = (const uint32 *) b64;
167 #else
168  /* 4 byte words */
169  /* what a brute force but fast! */
170  uint8 *y = (uint8 *) X;
171 
172  y[0] = b64[3];
173  y[1] = b64[2];
174  y[2] = b64[1];
175  y[3] = b64[0];
176  y[4] = b64[7];
177  y[5] = b64[6];
178  y[6] = b64[5];
179  y[7] = b64[4];
180  y[8] = b64[11];
181  y[9] = b64[10];
182  y[10] = b64[9];
183  y[11] = b64[8];
184  y[12] = b64[15];
185  y[13] = b64[14];
186  y[14] = b64[13];
187  y[15] = b64[12];
188  y[16] = b64[19];
189  y[17] = b64[18];
190  y[18] = b64[17];
191  y[19] = b64[16];
192  y[20] = b64[23];
193  y[21] = b64[22];
194  y[22] = b64[21];
195  y[23] = b64[20];
196  y[24] = b64[27];
197  y[25] = b64[26];
198  y[26] = b64[25];
199  y[27] = b64[24];
200  y[28] = b64[31];
201  y[29] = b64[30];
202  y[30] = b64[29];
203  y[31] = b64[28];
204  y[32] = b64[35];
205  y[33] = b64[34];
206  y[34] = b64[33];
207  y[35] = b64[32];
208  y[36] = b64[39];
209  y[37] = b64[38];
210  y[38] = b64[37];
211  y[39] = b64[36];
212  y[40] = b64[43];
213  y[41] = b64[42];
214  y[42] = b64[41];
215  y[43] = b64[40];
216  y[44] = b64[47];
217  y[45] = b64[46];
218  y[46] = b64[45];
219  y[47] = b64[44];
220  y[48] = b64[51];
221  y[49] = b64[50];
222  y[50] = b64[49];
223  y[51] = b64[48];
224  y[52] = b64[55];
225  y[53] = b64[54];
226  y[54] = b64[53];
227  y[55] = b64[52];
228  y[56] = b64[59];
229  y[57] = b64[58];
230  y[58] = b64[57];
231  y[59] = b64[56];
232  y[60] = b64[63];
233  y[61] = b64[62];
234  y[62] = b64[61];
235  y[63] = b64[60];
236 #endif
237 
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);
254 
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);
271 
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);
288 
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);
305 
306  ctx->md5_sta += A;
307  ctx->md5_stb += B;
308  ctx->md5_stc += C;
309  ctx->md5_std += D;
310 }
311 
312 static void
314 {
315  unsigned int gap;
316 
317  /* Don't count up padding. Keep md5_n. */
318  gap = MD5_BUFLEN - ctx->md5_i;
319  if (gap > 8)
320  {
321  memmove(ctx->md5_buf + ctx->md5_i, md5_paddat,
322  gap - sizeof(ctx->md5_n));
323  }
324  else
325  {
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));
331  }
332 
333  /* 8 byte word */
334 #ifndef WORDS_BIGENDIAN
335  memmove(&ctx->md5_buf[56], &ctx->md5_n8[0], 8);
336 #else
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];
345 #endif
346 
347  md5_calc(ctx->md5_buf, ctx);
348 }
349 
350 static void
352 {
353  /* 4 byte words */
354 #ifndef WORDS_BIGENDIAN
355  memmove(digest, &ctx->md5_st8[0], 16);
356 #else
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];
373 #endif
374 }
375 
376 
377 /* External routines for this MD5 implementation */
378 
379 /*
380  * pg_md5_init
381  *
382  * Initialize a MD5 context.
383  */
384 void
386 {
387  ctx->md5_n = 0;
388  ctx->md5_i = 0;
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));
394 }
395 
396 
397 /*
398  * pg_md5_update
399  *
400  * Update a MD5 context.
401  */
402 void
403 pg_md5_update(pg_md5_ctx *ctx, const uint8 *data, size_t len)
404 {
405  unsigned int gap,
406  i;
407 
408  ctx->md5_n += len * 8; /* byte to bit */
409  gap = MD5_BUFLEN - ctx->md5_i;
410 
411  if (len >= gap)
412  {
413  memmove(ctx->md5_buf + ctx->md5_i, data, gap);
414  md5_calc(ctx->md5_buf, ctx);
415 
416  for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN)
417  md5_calc(data + i, ctx);
418 
419  ctx->md5_i = len - i;
420  memmove(ctx->md5_buf, data + i, ctx->md5_i);
421  }
422  else
423  {
424  memmove(ctx->md5_buf + ctx->md5_i, data, len);
425  ctx->md5_i += len;
426  }
427 }
428 
429 /*
430  * pg_md5_final
431  *
432  * Finalize a MD5 context.
433  */
434 void
436 {
437  md5_pad(ctx);
438  md5_result(dest, ctx);
439 }
unsigned int uint32
Definition: c.h:506
unsigned char uint8
Definition: c.h:504
int y
Definition: isn.c:72
int i
Definition: isn.c:73
#define Sj
Definition: md5.c:104
#define Sc
Definition: md5.c:95
#define Sd
Definition: md5.c:96
#define ROUND2(a, b, c, d, k, s, i)
Definition: md5.c:72
static void md5_result(uint8 *digest, pg_md5_ctx *ctx)
Definition: md5.c:351
#define Sn
Definition: md5.c:109
void pg_md5_init(pg_md5_ctx *ctx)
Definition: md5.c:385
#define Sh
Definition: md5.c:101
#define Sa
Definition: md5.c:93
void pg_md5_update(pg_md5_ctx *ctx, const uint8 *data, size_t len)
Definition: md5.c:403
#define MD5_B0
Definition: md5.c:114
#define Se
Definition: md5.c:98
#define ROUND3(a, b, c, d, k, s, i)
Definition: md5.c:79
void pg_md5_final(pg_md5_ctx *ctx, uint8 *dest)
Definition: md5.c:435
#define Sg
Definition: md5.c:100
#define Sk
Definition: md5.c:105
#define Si
Definition: md5.c:103
#define ROUND1(a, b, c, d, k, s, i)
Definition: md5.c:65
#define Sp
Definition: md5.c:111
#define MD5_C0
Definition: md5.c:115
#define Sf
Definition: md5.c:99
static const uint8 md5_paddat[MD5_BUFLEN]
Definition: md5.c:142
#define ROUND4(a, b, c, d, k, s, i)
Definition: md5.c:86
#define MD5_D0
Definition: md5.c:116
static void md5_pad(pg_md5_ctx *ctx)
Definition: md5.c:313
#define Sb
Definition: md5.c:94
#define Sl
Definition: md5.c:106
static const uint32 T[65]
Definition: md5.c:119
#define Sm
Definition: md5.c:108
#define MD5_A0
Definition: md5.c:113
static void md5_calc(const uint8 *b64, pg_md5_ctx *ctx)
Definition: md5.c:158
#define So
Definition: md5.c:110
#define MD5_BUFLEN
Definition: md5_int.h:51
const void size_t len
const void * data
unsigned int md5_i
Definition: md5_int.h:76
uint8 md5_buf[MD5_BUFLEN]
Definition: md5_int.h:77