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  */
body(MD5_CTX * ctx,const void * data,unsigned long size)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 
MD5_Init(MD5_CTX * ctx)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 
MD5_Update(MD5_CTX * ctx,const void * data,unsigned long size)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 
MD5_Final(unsigned char * result,MD5_CTX * ctx)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 **************************************************************************/
md5_buffer(const unsigned char * buffer,size_t len,unsigned char * resblock)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 **************************************************************************/
create_md5sum(const unsigned char * input,int len,char output[MD5_HEX_BYTES+1])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 }
348