2
* Copyright (C) 2002-2024 by the Widelands Development Team
4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU General Public License
6
* as published by the Free Software Foundation; either version 2
7
* of the License, or (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, see <https://www.gnu.org/licenses/>.
19
/* md5.cc - Functions to compute MD5 message digest of files or memory blocks
20
* according to the definition of MD5 in RFC 1321 from April 1992.
22
* Thanks to Ulrich Drepper for the md5sum example code.
27
#include "base/macros.h"
30
* Create a hex string out of the MD5 checksum.
32
std::string Md5Checksum::str() const {
35
for (uint8_t d : data) {
37
snprintf(buf, sizeof(buf), "%02x", d);
44
/********************************************************************
46
* Down here: private functions originally from Ulrich Drepper
48
* From GNU textutils. md5.c
49
*******************************************************************/
51
static const uint8_t fillbuf[64] = {0x80, 0 /*, 0, 0, ... 0 */};
53
/* Process the remaining bytes in the internal buffer and the usual
54
prolog according to the standard and write the result to RESBUF.
56
IMPORTANT: On some systems it is required that RESBUF is correctly
57
aligned for a 32 bits value. */
58
void* md5_finish_ctx(Md5Ctx* const ctx, void* const resbuf) {
59
/* Take yet unprocessed bytes into account. */
60
uint32_t bytes = ctx->buflen;
63
/* Now count remaining bytes. */
64
ctx->total[0] += bytes;
65
if (ctx->total[0] < bytes) {
69
pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
70
memcpy(&ctx->buffer[bytes], fillbuf, pad);
72
// Put the 64-bit file length in *bits* at the end of the buffer.
73
GCC_DIAG_OFF("-Wstrict-aliasing");
74
*reinterpret_cast<uint32_t*>(&ctx->buffer[bytes + pad]) = (ctx->total[0] << 3);
75
*reinterpret_cast<uint32_t*>(&ctx->buffer[bytes + pad + 4]) =
76
((ctx->total[1] << 3) | (ctx->total[0] >> 29));
77
GCC_DIAG_ON("-Wstrict-aliasing");
79
/* Process last bytes. */
80
md5_process_block(ctx->buffer, bytes + pad + 8, ctx);
82
static_cast<uint32_t*>(resbuf)[0] = ctx->A;
83
static_cast<uint32_t*>(resbuf)[1] = ctx->B;
84
static_cast<uint32_t*>(resbuf)[2] = ctx->C;
85
static_cast<uint32_t*>(resbuf)[3] = ctx->D;
90
/* Processes some bytes in the internal buffer */
91
void md5_process_bytes(void const* buffer, uint32_t len, struct Md5Ctx* const ctx) {
92
/* When we already have some bits in our internal buffer concatenate
94
if (ctx->buflen != 0) {
95
uint32_t left_over = ctx->buflen;
96
uint32_t add = 128 - left_over > len ? len : 128 - left_over;
98
memcpy(&ctx->buffer[left_over], buffer, add);
101
if (left_over + add > 64) {
102
md5_process_block(ctx->buffer, (left_over + add) & ~63, ctx);
103
/* The regions in the following copy operation cannot overlap. */
104
memcpy(ctx->buffer, &ctx->buffer[(left_over + add) & ~63], (left_over + add) & 63);
105
ctx->buflen = (left_over + add) & 63;
108
buffer = static_cast<const char*>(buffer) + add;
112
/* Process available complete blocks. */
114
md5_process_block(buffer, len & ~63, ctx);
115
buffer = static_cast<const char*>(buffer) + (len & ~63);
119
/* Move remaining bytes in internal buffer. */
121
memcpy(ctx->buffer, buffer, len);
126
/* These are the four functions used in the four steps of the MD5 algorithm
127
and defined in the RFC 1321. The first function is a little bit optimized
128
(as found in Colin Plumbs public domain implementation). */
129
/* #define FF(b, c, d) ((b & c) | (~b & d)) */
130
#define FF(b, c, d) (d ^ (b & (c ^ d)))
131
#define FG(b, c, d) FF(d, b, c)
132
#define FH(b, c, d) (b ^ c ^ d)
133
#define FI(b, c, d) (c ^ (b | ~d))
135
/* Process LEN bytes of BUFFER, accumulating context into CTX.
136
It is assumed that LEN % 64 == 0. */
138
void md5_process_block(void const* const buffer, uint32_t const len, Md5Ctx* const ctx) {
139
uint32_t correct_words[16];
140
uint32_t const* words = static_cast<uint32_t const*>(buffer);
141
uint32_t const nwords = len / sizeof(uint32_t);
142
uint32_t const* const endp = words + nwords;
148
/* First increment the byte count. RFC 1321 specifies the possible
149
length of the file up to 2^64 bits. Here we only compute the
150
number of bytes. Do a double word increment. */
151
ctx->total[0] += len;
152
if (ctx->total[0] < len) {
156
/* Process all bytes in the buffer with 64 bytes in each round of
158
while (words < endp) {
159
uint32_t* cwp = correct_words;
160
uint32_t const A_save = A;
161
uint32_t const B_save = B;
162
uint32_t const C_save = C;
163
uint32_t const D_save = D;
165
/* First round: using the given function, the context and a constant
166
the next context is computed. Because the algorithms processing
167
unit is a 32-bit word and it is determined to work on words in
168
little endian byte order we perhaps have to change the byte order
169
before the computation. To reduce the work for the next steps
170
we store the swapped words in the array CORRECT_WORDS. */
172
#define OP(a, b, c, d, s, T) \
174
a += FF(b, c, d) + (*cwp++ = (*words)) + T; \
180
/* It is unfortunate that C does not provide an operator for
181
cyclic rotation. Hope the C compiler is smart enough. */
182
#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
184
/* Before we start, one word to the strange constants.
185
They are defined in RFC 1321 as
187
T[i] = static_cast<int32_t>(4294967296.0 * fabs (sin (i))), i=1..64
191
OP(A, B, C, D, 7, 0xd76aa478);
192
OP(D, A, B, C, 12, 0xe8c7b756);
193
OP(C, D, A, B, 17, 0x242070db);
194
OP(B, C, D, A, 22, 0xc1bdceee);
195
OP(A, B, C, D, 7, 0xf57c0faf);
196
OP(D, A, B, C, 12, 0x4787c62a);
197
OP(C, D, A, B, 17, 0xa8304613);
198
OP(B, C, D, A, 22, 0xfd469501);
199
OP(A, B, C, D, 7, 0x698098d8);
200
OP(D, A, B, C, 12, 0x8b44f7af);
201
OP(C, D, A, B, 17, 0xffff5bb1);
202
OP(B, C, D, A, 22, 0x895cd7be);
203
OP(A, B, C, D, 7, 0x6b901122);
204
OP(D, A, B, C, 12, 0xfd987193);
205
OP(C, D, A, B, 17, 0xa679438e);
206
OP(B, C, D, A, 22, 0x49b40821);
208
/* For the second to fourth round we have the possibly swapped words
209
in CORRECT_WORDS. Redefine the macro to take an additional first
210
argument specifying the function to use. */
212
#define OP(f, a, b, c, d, k, s, T) \
214
a += f(b, c, d) + correct_words[k] + T; \
220
OP(FG, A, B, C, D, 1, 5, 0xf61e2562);
221
OP(FG, D, A, B, C, 6, 9, 0xc040b340);
222
OP(FG, C, D, A, B, 11, 14, 0x265e5a51);
223
OP(FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
224
OP(FG, A, B, C, D, 5, 5, 0xd62f105d);
225
OP(FG, D, A, B, C, 10, 9, 0x02441453);
226
OP(FG, C, D, A, B, 15, 14, 0xd8a1e681);
227
OP(FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
228
OP(FG, A, B, C, D, 9, 5, 0x21e1cde6);
229
OP(FG, D, A, B, C, 14, 9, 0xc33707d6);
230
OP(FG, C, D, A, B, 3, 14, 0xf4d50d87);
231
OP(FG, B, C, D, A, 8, 20, 0x455a14ed);
232
OP(FG, A, B, C, D, 13, 5, 0xa9e3e905);
233
OP(FG, D, A, B, C, 2, 9, 0xfcefa3f8);
234
OP(FG, C, D, A, B, 7, 14, 0x676f02d9);
235
OP(FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
238
OP(FH, A, B, C, D, 5, 4, 0xfffa3942);
239
OP(FH, D, A, B, C, 8, 11, 0x8771f681);
240
OP(FH, C, D, A, B, 11, 16, 0x6d9d6122);
241
OP(FH, B, C, D, A, 14, 23, 0xfde5380c);
242
OP(FH, A, B, C, D, 1, 4, 0xa4beea44);
243
OP(FH, D, A, B, C, 4, 11, 0x4bdecfa9);
244
OP(FH, C, D, A, B, 7, 16, 0xf6bb4b60);
245
OP(FH, B, C, D, A, 10, 23, 0xbebfbc70);
246
OP(FH, A, B, C, D, 13, 4, 0x289b7ec6);
247
OP(FH, D, A, B, C, 0, 11, 0xeaa127fa);
248
OP(FH, C, D, A, B, 3, 16, 0xd4ef3085);
249
OP(FH, B, C, D, A, 6, 23, 0x04881d05);
250
OP(FH, A, B, C, D, 9, 4, 0xd9d4d039);
251
OP(FH, D, A, B, C, 12, 11, 0xe6db99e5);
252
OP(FH, C, D, A, B, 15, 16, 0x1fa27cf8);
253
OP(FH, B, C, D, A, 2, 23, 0xc4ac5665);
256
OP(FI, A, B, C, D, 0, 6, 0xf4292244);
257
OP(FI, D, A, B, C, 7, 10, 0x432aff97);
258
OP(FI, C, D, A, B, 14, 15, 0xab9423a7);
259
OP(FI, B, C, D, A, 5, 21, 0xfc93a039);
260
OP(FI, A, B, C, D, 12, 6, 0x655b59c3);
261
OP(FI, D, A, B, C, 3, 10, 0x8f0ccc92);
262
OP(FI, C, D, A, B, 10, 15, 0xffeff47d);
263
OP(FI, B, C, D, A, 1, 21, 0x85845dd1);
264
OP(FI, A, B, C, D, 8, 6, 0x6fa87e4f);
265
OP(FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
266
OP(FI, C, D, A, B, 6, 15, 0xa3014314);
267
OP(FI, B, C, D, A, 13, 21, 0x4e0811a1);
268
OP(FI, A, B, C, D, 4, 6, 0xf7537e82);
269
OP(FI, D, A, B, C, 11, 10, 0xbd3af235);
270
OP(FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
271
OP(FI, B, C, D, A, 9, 21, 0xeb86d391);
273
/* Add the starting values of the context. */
280
/* Put checksum in context given as argument. */