Freeciv-3.3: /fast/freeciv/nightly/main/utility/md5.c Source File

Freeciv-3.3

Loading...
Searching...
No Matches
md5.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14/*
15 * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
16 * MD5 Message-Digest Algorithm (RFC 1321).
17 *
18 * Homepage:
19 * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
20 *
21 * Author:
22 * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
23 *
24 * This software was written by Alexander Peslyak in 2001. No copyright is
25 * claimed, and the software is hereby placed in the public domain.
26 * In case this attempt to disclaim copyright and place the software in the
27 * public domain is deemed null and void, then the software is
28 * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
29 * general public under the following terms:
30 *
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted.
33 *
34 * There's ABSOLUTELY NO WARRANTY, express or implied.
35 *
36 * (This is a heavily cut-down "BSD license".)
37 *
38 * This differs from Colin Plumb's older public domain implementation in that
39 * no exactly 32-bit integer data type is required (any 32-bit or wider
40 * unsigned integer data type will do), there's no compile-time endianness
41 * configuration, and the function prototypes match OpenSSL's. No code from
42 * Colin Plumb's implementation has been reused; this comment merely compares
43 * the properties of the two independent implementations.
44 *
45 * The primary goals of this implementation are portability and ease of use.
46 * It is meant to be fast, but not as fast as possible. Some known
47 * optimizations are not included to reduce source code size and avoid
48 * compile-time configuration.
49 */
50
51/*
52 * Freeciv changes relative to upstream:
53 * - Reformatting and other cosmetic changes to fit in with Freeciv coding
54 * conventions.
55 * - Don't expose the init/update/final interface to the rest of Freeciv
56 * in md5.h; just expose a single high-level function which calculates
57 * the checksum on a buffer (with the result as an ASCII string).
58 * - Optimized version of SET() has been dropped.
59 *
60 * Upstream version is revision 1.15 from:
61 * https://cvsweb.openwall.com/cgi/cvsweb.cgi/Owl/packages/popa3d/popa3d/md5/md5.c
62 */
63
64#ifdef HAVE_CONFIG_H
65#include <fc_config.h>
66#endif
67
68#include <stdio.h>
69#include <string.h>
70
71#include "md5.h"
72
73/* Any 32-bit or wider unsigned integer data type will do */
74 typedef unsigned int MD5_u32plus;
75
76 typedef struct {
77 MD5_u32plus lo, hi;
78 MD5_u32plus a, b, c, d;
79 unsigned char buffer[64];
80 MD5_u32plus block[16];
81} MD5_CTX;
82
83/*
84 * The basic MD5 functions.
85 *
86 * F and G are optimized compared to their RFC 1321 definitions for
87 * architectures that lack an AND-NOT instruction, just like in Colin Plumb's
88 * implementation.
89 */
90#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
91#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
92#define H(x, y, z) (((x) ^ (y)) ^ (z))
93#define H2(x, y, z) ((x) ^ ((y) ^ (z)))
94#define I(x, y, z) ((y) ^ ((x) | ~(z)))
95
96/*
97 * The MD5 transformation for all four rounds.
98 */
99#define STEP(f, a, b, c, d, x, t, s) \
100 (a) += f((b), (c), (d)) + (x) + (t); \
101 (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
102 (a) += (b);
103
104/*
105 * SET reads 4 input bytes in little-endian byte order and stores them in a
106 * properly aligned word in host byte order.
107 */
108#define SET(n) \
109 (ctx->block[(n)] = \
110 (MD5_u32plus)ptr[(n) * 4] | \
111 ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
112 ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
113 ((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
114#define GET(n) \
115 (ctx->block[(n)])
116
117/*
118 * This processes one or more 64-byte data blocks, but does NOT update the bit
119 * counters. There are no alignment requirements.
120 */
121 static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
122{
123 const unsigned char *ptr;
124 MD5_u32plus a, b, c, d;
125 MD5_u32plus saved_a, saved_b, saved_c, saved_d;
126
127 ptr = (const unsigned char *)data;
128
129 a = ctx->a;
130 b = ctx->b;
131 c = ctx->c;
132 d = ctx->d;
133
134 do {
135 saved_a = a;
136 saved_b = b;
137 saved_c = c;
138 saved_d = d;
139
140/* Round 1 */
141 STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
142 STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
143 STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
144 STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
145 STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
146 STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
147 STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
148 STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
149 STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
150 STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
151 STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
152 STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
153 STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
154 STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
155 STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
156 STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
157
158/* Round 2 */
159 STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
160 STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
161 STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
162 STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
163 STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
164 STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
165 STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
166 STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
167 STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
168 STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
169 STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
170 STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
171 STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
172 STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
173 STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
174 STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
175
176/* Round 3 */
177 STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
178 STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11)
179 STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
180 STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23)
181 STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
182 STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11)
183 STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
184 STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23)
185 STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
186 STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11)
187 STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
188 STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23)
189 STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
190 STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11)
191 STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
192 STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23)
193
194/* Round 4 */
195 STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
196 STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
197 STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
198 STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
199 STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
200 STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
201 STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
202 STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
203 STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
204 STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
205 STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
206 STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
207 STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
208 STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
209 STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
210 STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
211
212 a += saved_a;
213 b += saved_b;
214 c += saved_c;
215 d += saved_d;
216
217 ptr += 64;
218 } while (size -= 64);
219
220 ctx->a = a;
221 ctx->b = b;
222 ctx->c = c;
223 ctx->d = d;
224
225 return ptr;
226}
227
228 static void MD5_Init(MD5_CTX *ctx)
229{
230 ctx->a = 0x67452301;
231 ctx->b = 0xefcdab89;
232 ctx->c = 0x98badcfe;
233 ctx->d = 0x10325476;
234
235 ctx->lo = 0;
236 ctx->hi = 0;
237}
238
239 static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
240{
241 MD5_u32plus saved_lo;
242 unsigned long used, available;
243
244 saved_lo = ctx->lo;
245 if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
246 ctx->hi++;
247 ctx->hi += size >> 29;
248
249 used = saved_lo & 0x3f;
250
251 if (used) {
252 available = 64 - used;
253
254 if (size < available) {
255 memcpy(&ctx->buffer[used], data, size);
256 return;
257 }
258
259 memcpy(&ctx->buffer[used], data, available);
260 data = (unsigned char *)data + available;
261 size -= available;
262 body(ctx, ctx->buffer, 64);
263 }
264
265 if (size >= 64) {
266 data = body(ctx, data, size & ~(unsigned long)0x3f);
267 size &= 0x3f;
268 }
269
270 memcpy(ctx->buffer, data, size);
271}
272
273#define OUT(dst, src) \
274 (dst)[0] = (unsigned char)(src); \
275 (dst)[1] = (unsigned char)((src) >> 8); \
276 (dst)[2] = (unsigned char)((src) >> 16); \
277 (dst)[3] = (unsigned char)((src) >> 24);
278
279 static void MD5_Final(unsigned char *result, MD5_CTX *ctx)
280{
281 unsigned long used, available;
282
283 used = ctx->lo & 0x3f;
284
285 ctx->buffer[used++] = 0x80;
286
287 available = 64 - used;
288
289 if (available < 8) {
290 memset(&ctx->buffer[used], 0, available);
291 body(ctx, ctx->buffer, 64);
292 used = 0;
293 available = 64;
294 }
295
296 memset(&ctx->buffer[used], 0, available - 8);
297
298 ctx->lo <<= 3;
299 OUT(&ctx->buffer[56], ctx->lo);
300 OUT(&ctx->buffer[60], ctx->hi);
301
302 body(ctx, ctx->buffer, 64);
303
304 OUT(&result[0], ctx->a);
305 OUT(&result[4], ctx->b);
306 OUT(&result[8], ctx->c);
307 OUT(&result[12], ctx->d);
308 memset(ctx, 0, sizeof(*ctx));
309}
310
311/**************************************************************************
312 Compute MD5 message digest for LEN octets beginning at BUFFER. The
313 result is always in little endian octet order, so that an octet-wise
314 output yields to the wanted ASCII representation of the message
315 digest.
316**************************************************************************/
317 static void md5_buffer(const unsigned char *buffer, size_t len,
318 unsigned char *resblock)
319{
320 MD5_CTX ctx;
321
322 /* Initialize the computation context. */
323 MD5_Init(&ctx);
324
325 /* Process whole buffer but last len % 64 bytes. */
326 MD5_Update(&ctx, buffer, len);
327
328 /* Put result in desired memory area. */
329 MD5_Final(resblock, &ctx);
330}
331
332/**************************************************************************
333 From a string, create an md5sum and store it in output in hex form.
334**************************************************************************/
335 void create_md5sum(const unsigned char *input, int len,
336 char output[MD5_HEX_BYTES + 1])
337{
338 unsigned char bin_buffer[MAX_MD5_BIN_BYTES];
339 size_t cnt;
340 char *ptr = output;
341
342 md5_buffer(input, len, bin_buffer);
343
344 for (cnt = 0; cnt < (MD5_HEX_BYTES / 2); cnt++, ptr += 2) {
345 sprintf(ptr, "%02x", bin_buffer[cnt]);
346 }
347}
incite_cost
char * incite_cost
Definition comments.c:74
create_md5sum
void create_md5sum(const unsigned char *input, int len, char output[MD5_HEX_BYTES+1])
Definition md5.c:335
GET
#define GET(n)
Definition md5.c:114
md5_buffer
static void md5_buffer(const unsigned char *buffer, size_t len, unsigned char *resblock)
Definition md5.c:317
STEP
#define STEP(f, a, b, c, d, x, t, s)
Definition md5.c:99
MD5_Final
static void MD5_Final(unsigned char *result, MD5_CTX *ctx)
Definition md5.c:279
body
static const void * body(MD5_CTX *ctx, const void *data, unsigned long size)
Definition md5.c:121
MD5_Init
static void MD5_Init(MD5_CTX *ctx)
Definition md5.c:228
SET
#define SET(n)
Definition md5.c:108
F
#define F(x, y, z)
Definition md5.c:90
OUT
#define OUT(dst, src)
Definition md5.c:273
I
#define I(x, y, z)
Definition md5.c:94
MD5_Update
static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
Definition md5.c:239
MD5_u32plus
unsigned int MD5_u32plus
Definition md5.c:74
G
#define G(x, y, z)
Definition md5.c:91
H
#define H(x, y, z)
Definition md5.c:92
H2
#define H2(x, y, z)
Definition md5.c:93
md5.h
MAX_MD5_BIN_BYTES
#define MAX_MD5_BIN_BYTES
Definition md5.h:24
MD5_HEX_BYTES
#define MD5_HEX_BYTES
Definition md5.h:21
len
int len
Definition packhand.c:127
size
size_t size
Definition specvec.h:72
MD5_CTX
Definition md5.c:76
MD5_CTX::hi
MD5_u32plus hi
Definition md5.c:77
MD5_CTX::a
MD5_u32plus a
Definition md5.c:78