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 static void
154 md5_calc(const uint8 *b64, pg_md5_ctx *ctx)
155 {
156  uint32 A = ctx->md5_sta;
157  uint32 B = ctx->md5_stb;
158  uint32 C = ctx->md5_stc;
159  uint32 D = ctx->md5_std;
160 
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;
168 
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
234 
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);
251 
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);
268 
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);
285 
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);
302 
303  ctx->md5_sta += A;
304  ctx->md5_stb += B;
305  ctx->md5_stc += C;
306  ctx->md5_std += D;
307 }
308 
309 static void
311 {
312  unsigned int gap;
313 
314  /* Don't count up padding. Keep md5_n. */
315  gap = MD5_BUFLEN - ctx->md5_i;
316  if (gap > 8)
317  {
318  memmove(ctx->md5_buf + ctx->md5_i, md5_paddat,
319  gap - sizeof(ctx->md5_n));
320  }
321  else
322  {
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));
328  }
329 
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
343 
344  md5_calc(ctx->md5_buf, ctx);
345 }
346 
347 static void
349 {
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
371 }
372 
373 
374 /* External routines for this MD5 implementation */
375 
376 /*
377  * pg_md5_init
378  *
379  * Initialize a MD5 context.
380  */
381 void
383 {
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));
391 }
392 
393 
394 /*
395  * pg_md5_update
396  *
397  * Update a MD5 context.
398  */
399 void
400 pg_md5_update(pg_md5_ctx *ctx, const uint8 *data, size_t len)
401 {
402  unsigned int gap,
403  i;
404 
405  ctx->md5_n += len * 8; /* byte to bit */
406  gap = MD5_BUFLEN - ctx->md5_i;
407 
408  if (len >= gap)
409  {
410  memmove(ctx->md5_buf + ctx->md5_i, data, gap);
411  md5_calc(ctx->md5_buf, ctx);
412 
413  for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN)
414  md5_calc(data + i, ctx);
415 
416  ctx->md5_i = len - i;
417  memmove(ctx->md5_buf, data + i, ctx->md5_i);
418  }
419  else
420  {
421  memmove(ctx->md5_buf + ctx->md5_i, data, len);
422  ctx->md5_i += len;
423  }
424 }
425 
426 /*
427  * pg_md5_final
428  *
429  * Finalize a MD5 context.
430  */
431 void
433 {
434  md5_pad(ctx);
435  md5_result(dest, ctx);
436 }
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:348
#define Sn
Definition: md5.c:109
void pg_md5_init(pg_md5_ctx *ctx)
Definition: md5.c:382
#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:400
#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:432
#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:310
#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:154
#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