"Fossies" - the Fresh Open Source Software Archive 
Member "geoipupdate-3.1.1/bin/md5.c" (23 Aug 2018, 10981 Bytes) of package /linux/misc/geoipupdate-3.1.1.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "md5.c" see the
Fossies "Dox" file reference documentation.
1 /* md5.c - MD5 Message-Digest Algorithm
2 * Copyright (C) 1995, 1996, 1998, 1999,
3 * 2000, 2001 Free Software Foundation, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2, or (at your option) any
8 * later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 *
19 * According to the definition of MD5 in RFC 1321 from April 1992.
20 * NOTE: This is *not* the same file as the one from glibc.
21 */
22 /* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */
23 /* Heavily modified for GnuPG by <wk@gnupg.org> */
24
25 #include <assert.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include "types.h"
31
32 #ifdef WORDS_BIGENDIAN
33 #define BIG_ENDIAN_HOST
34 #endif
35
36 //#define DIM(v) (sizeof(v)/sizeof((v)[0]))
37 #define wipememory2(_ptr, _set, _len) \
38 do { \
39 volatile char *_vptr = (volatile char *)(_ptr); \
40 size_t _vlen = (_len); \
41 while (_vlen) { \
42 *_vptr = (_set); \
43 _vptr++; \
44 _vlen--; \
45 } \
46 } while (0)
47 #define wipememory(_ptr, _len) wipememory2(_ptr, 0, _len)
48 #define rol(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
49
50 typedef struct {
51 u32 A, B, C, D; /* chaining variables */
52 u32 nblocks;
53 byte buf[64];
54 int count;
55 } MD5_CONTEXT;
56
57 void md5_init(MD5_CONTEXT *ctx) {
58 ctx->A = 0x67452301;
59 ctx->B = 0xefcdab89;
60 ctx->C = 0x98badcfe;
61 ctx->D = 0x10325476;
62
63 ctx->nblocks = 0;
64 ctx->count = 0;
65 }
66
67 /* These are the four functions used in the four steps of the MD5 algorithm
68 and defined in the RFC 1321. The first function is a little bit optimized
69 (as found in Colin Plumbs public domain implementation). */
70 /* #define FF(b, c, d) ((b & c) | (~b & d)) */
71 #define FF(b, c, d) (d ^ (b & (c ^ d)))
72 #define FG(b, c, d) FF(d, b, c)
73 #define FH(b, c, d) (b ^ c ^ d)
74 #define FI(b, c, d) (c ^ (b | ~d))
75
76 static void burn_stack(int bytes) {
77 char buf[128];
78
79 wipememory(buf, sizeof buf);
80 bytes -= sizeof buf;
81 if (bytes > 0) {
82 burn_stack(bytes);
83 }
84 }
85
86 /****************
87 * transform n*64 bytes
88 */
89 static void
90 /*transform( MD5_CONTEXT *ctx, const void *buffer, size_t len )*/
91 transform(MD5_CONTEXT *ctx, byte *data) {
92 u32 correct_words[16];
93 u32 A = ctx->A;
94 u32 B = ctx->B;
95 u32 C = ctx->C;
96 u32 D = ctx->D;
97 u32 *cwp = correct_words;
98
99 #ifdef BIG_ENDIAN_HOST
100 {
101 int i;
102 byte *p2, *p1;
103 for (i = 0, p1 = data, p2 = (byte *)correct_words; i < 16;
104 i++, p2 += 4) {
105 p2[3] = *p1++;
106 p2[2] = *p1++;
107 p2[1] = *p1++;
108 p2[0] = *p1++;
109 }
110 }
111 #else
112 memcpy(correct_words, data, 64);
113 #endif
114
115 #define OP(a, b, c, d, s, T) \
116 do { \
117 a += FF(b, c, d) + (*cwp++) + T; \
118 a = rol(a, s); \
119 a += b; \
120 } while (0)
121
122 /* Before we start, one word about the strange constants.
123 They are defined in RFC 1321 as
124
125 T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
126 */
127
128 /* Round 1. */
129 OP(A, B, C, D, 7, 0xd76aa478);
130 OP(D, A, B, C, 12, 0xe8c7b756);
131 OP(C, D, A, B, 17, 0x242070db);
132 OP(B, C, D, A, 22, 0xc1bdceee);
133 OP(A, B, C, D, 7, 0xf57c0faf);
134 OP(D, A, B, C, 12, 0x4787c62a);
135 OP(C, D, A, B, 17, 0xa8304613);
136 OP(B, C, D, A, 22, 0xfd469501);
137 OP(A, B, C, D, 7, 0x698098d8);
138 OP(D, A, B, C, 12, 0x8b44f7af);
139 OP(C, D, A, B, 17, 0xffff5bb1);
140 OP(B, C, D, A, 22, 0x895cd7be);
141 OP(A, B, C, D, 7, 0x6b901122);
142 OP(D, A, B, C, 12, 0xfd987193);
143 OP(C, D, A, B, 17, 0xa679438e);
144 OP(B, C, D, A, 22, 0x49b40821);
145
146 #undef OP
147 #define OP(f, a, b, c, d, k, s, T) \
148 do { \
149 a += f(b, c, d) + correct_words[k] + T; \
150 a = rol(a, s); \
151 a += b; \
152 } while (0)
153
154 /* Round 2. */
155 OP(FG, A, B, C, D, 1, 5, 0xf61e2562);
156 OP(FG, D, A, B, C, 6, 9, 0xc040b340);
157 OP(FG, C, D, A, B, 11, 14, 0x265e5a51);
158 OP(FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
159 OP(FG, A, B, C, D, 5, 5, 0xd62f105d);
160 OP(FG, D, A, B, C, 10, 9, 0x02441453);
161 OP(FG, C, D, A, B, 15, 14, 0xd8a1e681);
162 OP(FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
163 OP(FG, A, B, C, D, 9, 5, 0x21e1cde6);
164 OP(FG, D, A, B, C, 14, 9, 0xc33707d6);
165 OP(FG, C, D, A, B, 3, 14, 0xf4d50d87);
166 OP(FG, B, C, D, A, 8, 20, 0x455a14ed);
167 OP(FG, A, B, C, D, 13, 5, 0xa9e3e905);
168 OP(FG, D, A, B, C, 2, 9, 0xfcefa3f8);
169 OP(FG, C, D, A, B, 7, 14, 0x676f02d9);
170 OP(FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
171
172 /* Round 3. */
173 OP(FH, A, B, C, D, 5, 4, 0xfffa3942);
174 OP(FH, D, A, B, C, 8, 11, 0x8771f681);
175 OP(FH, C, D, A, B, 11, 16, 0x6d9d6122);
176 OP(FH, B, C, D, A, 14, 23, 0xfde5380c);
177 OP(FH, A, B, C, D, 1, 4, 0xa4beea44);
178 OP(FH, D, A, B, C, 4, 11, 0x4bdecfa9);
179 OP(FH, C, D, A, B, 7, 16, 0xf6bb4b60);
180 OP(FH, B, C, D, A, 10, 23, 0xbebfbc70);
181 OP(FH, A, B, C, D, 13, 4, 0x289b7ec6);
182 OP(FH, D, A, B, C, 0, 11, 0xeaa127fa);
183 OP(FH, C, D, A, B, 3, 16, 0xd4ef3085);
184 OP(FH, B, C, D, A, 6, 23, 0x04881d05);
185 OP(FH, A, B, C, D, 9, 4, 0xd9d4d039);
186 OP(FH, D, A, B, C, 12, 11, 0xe6db99e5);
187 OP(FH, C, D, A, B, 15, 16, 0x1fa27cf8);
188 OP(FH, B, C, D, A, 2, 23, 0xc4ac5665);
189
190 /* Round 4. */
191 OP(FI, A, B, C, D, 0, 6, 0xf4292244);
192 OP(FI, D, A, B, C, 7, 10, 0x432aff97);
193 OP(FI, C, D, A, B, 14, 15, 0xab9423a7);
194 OP(FI, B, C, D, A, 5, 21, 0xfc93a039);
195 OP(FI, A, B, C, D, 12, 6, 0x655b59c3);
196 OP(FI, D, A, B, C, 3, 10, 0x8f0ccc92);
197 OP(FI, C, D, A, B, 10, 15, 0xffeff47d);
198 OP(FI, B, C, D, A, 1, 21, 0x85845dd1);
199 OP(FI, A, B, C, D, 8, 6, 0x6fa87e4f);
200 OP(FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
201 OP(FI, C, D, A, B, 6, 15, 0xa3014314);
202 OP(FI, B, C, D, A, 13, 21, 0x4e0811a1);
203 OP(FI, A, B, C, D, 4, 6, 0xf7537e82);
204 OP(FI, D, A, B, C, 11, 10, 0xbd3af235);
205 OP(FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
206 OP(FI, B, C, D, A, 9, 21, 0xeb86d391);
207
208 /* Put checksum in context given as argument. */
209 ctx->A += A;
210 ctx->B += B;
211 ctx->C += C;
212 ctx->D += D;
213 }
214
215 /* The routine updates the message-digest context to
216 * account for the presence of each of the characters inBuf[0..inLen-1]
217 * in the message whose digest is being computed.
218 */
219 void md5_write(MD5_CONTEXT *hd, byte *inbuf, size_t inlen) {
220 if (hd->count == 64) { /* flush the buffer */
221 transform(hd, hd->buf);
222 burn_stack(80 + 6 * sizeof(void *));
223 hd->count = 0;
224 hd->nblocks++;
225 }
226 if (!inbuf) {
227 return;
228 }
229 if (hd->count) {
230 for (; inlen && hd->count < 64; inlen--) {
231 hd->buf[hd->count++] = *inbuf++;
232 }
233 md5_write(hd, NULL, 0);
234 if (!inlen) {
235 return;
236 }
237 }
238
239 while (inlen >= 64) {
240 transform(hd, inbuf);
241 hd->count = 0;
242 hd->nblocks++;
243 inlen -= 64;
244 inbuf += 64;
245 }
246 burn_stack(80 + 6 * sizeof(void *));
247 for (; inlen && hd->count < 64; inlen--) {
248 hd->buf[hd->count++] = *inbuf++;
249 }
250 }
251 /* The routine final terminates the message-digest computation and
252 * ends with the desired message digest in mdContext->digest[0...15].
253 * The handle is prepared for a new MD5 cycle.
254 * Returns 16 bytes representing the digest.
255 */
256
257 void md5_final(MD5_CONTEXT *hd) {
258 u32 t, msb, lsb;
259 byte *p;
260
261 md5_write(hd, NULL, 0); /* flush */
262 ;
263
264 t = hd->nblocks;
265 /* multiply by 64 to make a byte count */
266 lsb = t << 6;
267 msb = t >> 26;
268 /* add the count */
269 t = lsb;
270 if ((lsb += hd->count) < t) {
271 msb++;
272 }
273 /* multiply by 8 to make a bit count */
274 t = lsb;
275 lsb <<= 3;
276 msb <<= 3;
277 msb |= t >> 29;
278
279 if (hd->count < 56) { /* enough room */
280 hd->buf[hd->count++] = 0x80; /* pad */
281 while (hd->count < 56) {
282 hd->buf[hd->count++] = 0; /* pad */
283 }
284 } else { /* need one extra block */
285 hd->buf[hd->count++] = 0x80; /* pad character */
286 while (hd->count < 64) {
287 hd->buf[hd->count++] = 0;
288 }
289 md5_write(hd, NULL, 0); /* flush */
290 ;
291 memset(hd->buf, 0, 56); /* fill next block with zeroes */
292 }
293 /* append the 64 bit count */
294 hd->buf[56] = lsb;
295 hd->buf[57] = lsb >> 8;
296 hd->buf[58] = lsb >> 16;
297 hd->buf[59] = lsb >> 24;
298 hd->buf[60] = msb;
299 hd->buf[61] = msb >> 8;
300 hd->buf[62] = msb >> 16;
301 hd->buf[63] = msb >> 24;
302 transform(hd, hd->buf);
303 burn_stack(80 + 6 * sizeof(void *));
304
305 p = hd->buf;
306 #ifdef BIG_ENDIAN_HOST
307 #define X(a) \
308 do { \
309 *p++ = hd->a; \
310 *p++ = hd->a >> 8; \
311 *p++ = hd->a >> 16; \
312 *p++ = hd->a >> 24; \
313 } while (0)
314 #else /* little endian */
315 #define X(a) \
316 do { \
317 *(u32 *)p = hd->a; \
318 p += 4; \
319 } while (0)
320 #endif
321 X(A);
322 X(B);
323 X(C);
324 X(D);
325 #undef X
326 }