aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2015-08-08 11:10:06 +0000
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2015-08-08 11:10:06 +0000
commitd0acbabefab836b815a0d1eed24f73605e9f6381 (patch)
tree1bcde3ec7ff99f83dcd43c37f544d4e80dba3769 /src
parentbfbff93d6e64b6cb32a987d55480c9717067f5b0 (diff)
downloadlibmicrohttpd-d0acbabefab836b815a0d1eed24f73605e9f6381.tar.gz
libmicrohttpd-d0acbabefab836b815a0d1eed24f73605e9f6381.zip
Update md5.c to version based on OpenBSD modifications,
distinguish between little endian and PDP endian.
Diffstat (limited to 'src')
-rw-r--r--src/microhttpd/MHD_byteorder.h152
-rw-r--r--src/microhttpd/md5.c413
-rw-r--r--src/microhttpd/md5.h58
3 files changed, 392 insertions, 231 deletions
diff --git a/src/microhttpd/MHD_byteorder.h b/src/microhttpd/MHD_byteorder.h
new file mode 100644
index 00000000..c0395b00
--- /dev/null
+++ b/src/microhttpd/MHD_byteorder.h
@@ -0,0 +1,152 @@
1/*
2 This file is part of libmicrohttpd
3 Copyright (C) 2015 Karlson2k (Evgeny Grin)
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library 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 GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library.
17 If not, see <http://www.gnu.org/licenses/>.
18*/
19
20/**
21 * @file microhttpd/MHD_byteorder.h
22 * @brief macro definitions for host byte order
23 * @author Karlson2k (Evgeny Grin)
24 */
25
26#ifndef MHD_BYTEORDER_H
27#define MHD_BYTEORDER_H
28
29#include "platform.h"
30
31#if HAVE_ENDIAN_H
32#include <endian.h>
33#endif
34
35#if HAVE_SYS_PARAM_H
36#include <sys/param.h>
37#endif
38
39#if HAVE_MACHINE_ENDIAN_H
40#include <machine/endian.h>
41#endif
42
43#if HAVE_SYS_ENDIAN_H
44#include <sys/endian.h>
45#endif
46
47#if HAVE_SYS_TYPES_H
48#include <sys/types.h>
49#endif
50
51#if HAVE_SYS_BYTEORDER_H
52#include <sys/byteorder.h>
53#endif
54
55#if HAVE_SYS_MACHINE_H
56#include <sys/machine.h>
57#endif
58
59#if HAVE_MACHINE_PARAM_H
60#include <machine/param.h>
61#endif
62
63#if HAVE_SYS_ISA_DEFS_H
64#include <sys/isa_defs.h>
65#endif
66
67#define _MHD_BIG_ENDIAN 4321
68#define _MHD_LITTLE_ENDIAN 1234
69#define _MHD_PDP_ENDIAN 2134
70
71#if defined(__BYTE_ORDER)
72#if defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN
73#define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN
74#elif defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN
75#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN
76#elif defined(__PDP_ENDIAN) && __BYTE_ORDER == __PDP_ENDIAN
77#define _MHD_BYTE_ORDER _MHD_PDP_ENDIAN
78#endif /* __BYTE_ORDER == __PDP_ENDIAN */
79#elif defined (BYTE_ORDER)
80#if defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN
81#define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN
82#elif defined(LITTLE_ENDIAN) && BYTE_ORDER == LITTLE_ENDIAN
83#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN
84#elif defined(PDP_ENDIAN) && BYTE_ORDER == PDP_ENDIAN
85#define _MHD_BYTE_ORDER _MHD_PDP_ENDIAN
86#endif /* __BYTE_ORDER == _PDP_ENDIAN */
87#elif defined (_BYTE_ORDER)
88#if defined(_BIG_ENDIAN) && _BYTE_ORDER == _BIG_ENDIAN
89#define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN
90#elif defined(_LITTLE_ENDIAN) && _BYTE_ORDER == _LITTLE_ENDIAN
91#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN
92#elif defined(_PDP_ENDIAN) && _BYTE_ORDER == _PDP_ENDIAN
93#define _MHD_BYTE_ORDER _MHD_PDP_ENDIAN
94#endif /* __BYTE_ORDER == _PDP_ENDIAN */
95#endif /* _BYTE_ORDER */
96
97#ifndef _MHD_BYTE_ORDER
98/* Byte order specification didn't detected in system headers */
99/* Try some guessing */
100
101#if (defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)) || \
102 (defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN))
103/* Seems that we are on big endian platform */
104#define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN
105#elif (defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)) || \
106 (defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN))
107/* Seems that we are on little endian platform */
108#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN
109#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || \
110 defined(_M_X64) || defined(_M_AMD64) || defined(i386) || defined(__i386) || \
111 defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || \
112 defined(_M_IX86) || defined(_X86_) || defined (__THW_INTEL__)
113/* x86 family is little endian */
114#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN
115#elif defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || \
116 defined(_MIPSEB) || defined(__MIPSEB) || defined(__MIPSEB__)
117/* Looks like we are on ARM/MIPS in big endian mode */
118#define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN
119#elif defined(__ARMEL__) || defined(__THUMBEL__) || defined(__AARCH64EL__) || \
120 defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__)
121/* Looks like we are on ARM/MIPS in little endian mode */
122#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN
123#elif defined(__m68k__) || defined(M68000) || defined(__hppa__) || defined(__hppa) || \
124 defined(__HPPA__) || defined(__370__) || defined(__THW_370__) || \
125 defined(__s390__) || defined(__s390x__) || defined(__SYSC_ZARCH__)
126/* Looks like we are on big endian platform */
127#define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN
128#elif defined(__ia64__) || defined(_IA64) || defined(__IA64__) || defined(__ia64) || \
129 defined(_M_IA64) || defined(__itanium__) || defined(__bfin__) || \
130 defined(__BFIN__) || defined(bfin) || defined(BFIN)
131/* Looks like we are on little endian platform */
132#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN
133#elif defined(_WIN32)
134/* W32 is always little endian on all platforms */
135#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN
136#elif defined(WORDS_BIGENDIAN)
137/* Use byte order detected by configure */
138#define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN
139#endif /* _WIN32 */
140
141#endif /* !_MHD_BYTE_ORDER */
142
143#ifdef _MHD_BYTE_ORDER
144/* Some safety checks */
145#if defined(WORDS_BIGENDIAN) && _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN
146#error Configure detected big endian byte order but headers specify different byte order
147#elif !defined(WORDS_BIGENDIAN) && _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN
148#error Configure did not detect big endian byte order but headers specify big endian byte order
149#endif /* !WORDS_BIGENDIAN && _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN */
150#endif /* _MHD_BYTE_ORDER */
151
152#endif /* !MHD_BYTEORDER_H */ \ No newline at end of file
diff --git a/src/microhttpd/md5.c b/src/microhttpd/md5.c
index e35d5f26..906ac356 100644
--- a/src/microhttpd/md5.c
+++ b/src/microhttpd/md5.c
@@ -15,136 +15,32 @@
15 * will fill a supplied 16-byte array with the digest. 15 * will fill a supplied 16-byte array with the digest.
16 */ 16 */
17 17
18/* Brutally hacked by John Walker back from ANSI C to K&R (no 18/* Based on OpenBSD modifications */
19 prototypes) to maintain the tradition that Netfone will compile
20 with Sun's original "cc". */
21 19
22#include "md5.h" 20#include "md5.h"
23 21#include "MHD_byteorder.h"
24 22
25#ifndef HIGHFIRST 23#define PUT_64BIT_LE(cp, value) do { \
26#define byteReverse(buf, len) /* Nothing */ 24 (cp)[7] = (uint8_t)((value) >> 56); \
27#else 25 (cp)[6] = (uint8_t)((value) >> 48); \
28/* 26 (cp)[5] = (uint8_t)((value) >> 40); \
29 * Note: this code is harmless on little-endian machines. 27 (cp)[4] = (uint8_t)((value) >> 32); \
30 */ 28 (cp)[3] = (uint8_t)((value) >> 24); \
31static void 29 (cp)[2] = (uint8_t)((value) >> 16); \
32byteReverse(unsigned char *buf, 30 (cp)[1] = (uint8_t)((value) >> 8); \
33 unsigned longs) 31 (cp)[0] = (uint8_t)((value)); } while (0)
34{ 32
35 uint32_t t; 33#define PUT_32BIT_LE(cp, value) do { \
36 do { 34 (cp)[3] = (uint8_t)((value) >> 24); \
37 t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 | 35 (cp)[2] = (uint8_t)((value) >> 16); \
38 ((unsigned) buf[1] << 8 | buf[0]); 36 (cp)[1] = (uint8_t)((value) >> 8); \
39 *(uint32_t *) buf = t; 37 (cp)[0] = (uint8_t)((value)); } while (0)
40 buf += 4; 38
41 } while (--longs); 39static uint8_t PADDING[MD5_BLOCK_SIZE] = {
42} 40 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
43#endif 41 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
44 42 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
45 43};
46/* The four core functions - F1 is optimized somewhat */
47
48/* #define F1(x, y, z) (x & y | ~x & z) */
49#define F1(x, y, z) (z ^ (x & (y ^ z)))
50#define F2(x, y, z) F1(z, x, y)
51#define F3(x, y, z) (x ^ y ^ z)
52#define F4(x, y, z) (y ^ (x | ~z))
53
54/* This is the central step in the MD5 algorithm. */
55#define MD5STEP(f, w, x, y, z, data, s) \
56 ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
57
58/*
59 * The core of the MD5 algorithm, this alters an existing MD5 hash to
60 * reflect the addition of 16 longwords of new data. MD5Update blocks
61 * the data and converts bytes into longwords for this routine.
62 */
63static void
64MD5Transform(uint32_t buf[4],
65 uint32_t in[16])
66{
67 uint32_t a, b, c, d;
68
69 a = buf[0];
70 b = buf[1];
71 c = buf[2];
72 d = buf[3];
73
74 MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
75 MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
76 MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
77 MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
78 MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
79 MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
80 MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
81 MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
82 MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
83 MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
84 MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
85 MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
86 MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
87 MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
88 MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
89 MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
90
91 MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
92 MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
93 MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
94 MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
95 MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
96 MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
97 MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
98 MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
99 MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
100 MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
101 MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
102 MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
103 MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
104 MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
105 MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
106 MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
107
108 MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
109 MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
110 MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
111 MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
112 MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
113 MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
114 MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
115 MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
116 MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
117 MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
118 MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
119 MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
120 MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
121 MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
122 MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
123 MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
124
125 MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
126 MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
127 MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
128 MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
129 MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
130 MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
131 MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
132 MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
133 MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
134 MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
135 MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
136 MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
137 MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
138 MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
139 MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
140 MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
141
142 buf[0] += a;
143 buf[1] += b;
144 buf[2] += c;
145 buf[3] += d;
146}
147
148 44
149/* 45/*
150 * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious 46 * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
@@ -153,13 +49,14 @@ MD5Transform(uint32_t buf[4],
153void 49void
154MD5Init(struct MD5Context *ctx) 50MD5Init(struct MD5Context *ctx)
155{ 51{
156 ctx->buf[0] = 0x67452301; 52 if (!ctx)
157 ctx->buf[1] = 0xefcdab89; 53 return;
158 ctx->buf[2] = 0x98badcfe; 54
159 ctx->buf[3] = 0x10325476; 55 ctx->count = 0;
160 56 ctx->state[0] = 0x67452301;
161 ctx->bits[0] = 0; 57 ctx->state[1] = 0xefcdab89;
162 ctx->bits[1] = 0; 58 ctx->state[2] = 0x98badcfe;
59 ctx->state[3] = 0x10325476;
163} 60}
164 61
165/* 62/*
@@ -167,101 +64,201 @@ MD5Init(struct MD5Context *ctx)
167 * of bytes. 64 * of bytes.
168 */ 65 */
169void 66void
170MD5Update(struct MD5Context *ctx, 67MD5Update(struct MD5Context *ctx, const unsigned char *input, size_t len)
171 const void *data,
172 unsigned len)
173{ 68{
174 const unsigned char *buf = data; 69 size_t have, need;
175 uint32_t t;
176 70
177 /* Update bitcount */ 71 if (!ctx || !input)
72 return;
178 73
179 t = ctx->bits[0]; 74 /* Check how many bytes we already have and how many more we need. */
180 if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t) 75 have = (size_t)((ctx->count >> 3) & (MD5_BLOCK_SIZE - 1));
181 ctx->bits[1]++; /* Carry from low to high */ 76 need = MD5_BLOCK_SIZE - have;
182 ctx->bits[1] += len >> 29;
183 77
184 t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ 78 /* Update bitcount */
79 ctx->count += (uint64_t)len << 3;
185 80
186 /* Handle any leading odd-sized chunks */ 81 if (len >= need)
187 82 {
188 if (t) { 83 if (have != 0)
189 unsigned char *p = (unsigned char *) ctx->in + t; 84 {
190 85 memcpy(ctx->buffer + have, input, need);
191 t = 64 - t; 86 MD5Transform(ctx->state, ctx->buffer);
192 if (len < t) { 87 input += need;
193 memcpy(p, buf, len); 88 len -= need;
194 return; 89 have = 0;
195 }
196 memcpy(p, buf, t);
197 byteReverse(ctx->in, 16);
198 MD5Transform(ctx->buf, (uint32_t *) ctx->in);
199 buf += t;
200 len -= t;
201 }
202 /* Process data in 64-byte chunks */
203
204 while (len >= 64) {
205 memcpy(ctx->in, buf, 64);
206 byteReverse(ctx->in, 16);
207 MD5Transform(ctx->buf, (uint32_t *) ctx->in);
208 buf += 64;
209 len -= 64;
210 } 90 }
211 91
212 /* Handle any remaining bytes of data. */ 92 /* Process data in MD5_BLOCK_SIZE-byte chunks. */
93 while (len >= MD5_BLOCK_SIZE)
94 {
95 MD5Transform(ctx->state, input);
96 input += MD5_BLOCK_SIZE;
97 len -= MD5_BLOCK_SIZE;
98 }
99 }
213 100
214 memcpy(ctx->in, buf, len); 101 /* Handle any remaining bytes of data. */
102 if (len != 0)
103 memcpy(ctx->buffer + have, input, len);
215} 104}
216 105
217/* 106/*
218 * Final wrapup - pad to 64-byte boundary with the bit pattern 107 * Pad pad to 64-byte boundary with the bit pattern
219 * 1 0* (64-bit count of bits processed, MSB-first) 108 * 1 0* (64-bit count of bits processed, MSB-first)
220 */ 109 */
221void 110void
222MD5Final (unsigned char digest[16], 111MD5Pad(struct MD5Context *ctx)
223 struct MD5Context *ctx)
224{ 112{
225 unsigned count; 113 uint8_t count[8];
226 unsigned char *p; 114 size_t padlen;
115
116 if (!ctx)
117 return;
118
119 /* Convert count to 8 bytes in little endian order. */
120 PUT_64BIT_LE(count, ctx->count);
121
122 /* Pad out to 56 mod 64. */
123 padlen = MD5_BLOCK_SIZE -
124 ((ctx->count >> 3) & (MD5_BLOCK_SIZE - 1));
125 if (padlen < 1 + 8)
126 padlen += MD5_BLOCK_SIZE;
127 MD5Update(ctx, PADDING, padlen - 8); /* padlen - 8 <= 64 */
128 MD5Update(ctx, count, 8);
129}
227 130
228 /* Compute number of bytes mod 64 */ 131/*
229 count = (ctx->bits[0] >> 3) & 0x3F; 132 * Final wrapup--call MD5Pad, fill in digest and zero out ctx.
133 */
134void
135MD5Final(unsigned char digest[MD5_DIGEST_SIZE], struct MD5Context *ctx)
136{
137 int i;
230 138
231 /* Set the first char of padding to 0x80. This is safe since there is 139 if (!ctx || !digest)
232 always at least one byte free */ 140 return;
233 p = ctx->in + count;
234 *p++ = 0x80;
235 141
236 /* Bytes of padding needed to make 64 bytes */ 142 MD5Pad(ctx);
237 count = 64 - 1 - count; 143 for (i = 0; i < 4; i++)
144 PUT_32BIT_LE(digest + i * 4, ctx->state[i]);
238 145
239 /* Pad out to 56 mod 64 */ 146 memset(ctx, 0, sizeof(*ctx));
240 if (count < 8) 147}
241 {
242 /* Two lots of padding: Pad the first block to 64 bytes */
243 memset(p, 0, count);
244 byteReverse(ctx->in, 16);
245 MD5Transform(ctx->buf, (uint32_t *) ctx->in);
246 148
247 /* Now fill the next block with 56 bytes */
248 memset(ctx->in, 0, 56);
249 }
250 else
251 {
252 /* Pad block to 56 bytes */
253 memset(p, 0, count - 8);
254 }
255 byteReverse(ctx->in, 14);
256 149
257 /* Append length in bits and transform */ 150/* The four core functions - F1 is optimized somewhat */
258 ((uint32_t *) ctx->in)[14] = ctx->bits[0]; 151
259 ((uint32_t *) ctx->in)[15] = ctx->bits[1]; 152/* #define F1(x, y, z) (x & y | ~x & z) */
153#define F1(x, y, z) (z ^ (x & (y ^ z)))
154#define F2(x, y, z) F1(z, x, y)
155#define F3(x, y, z) (x ^ y ^ z)
156#define F4(x, y, z) (y ^ (x | ~z))
157
158/* This is the central step in the MD5 algorithm. */
159#define MD5STEP(f, w, x, y, z, data, s) \
160 ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
161
162/*
163 * The core of the MD5 algorithm, this alters an existing MD5 hash to
164 * reflect the addition of 16 longwords of new data. MD5Update blocks
165 * the data and converts bytes into longwords for this routine.
166 */
167void
168MD5Transform(uint32_t state[4], const uint8_t block[MD5_BLOCK_SIZE])
169{
170 uint32_t a, b, c, d, in[MD5_BLOCK_SIZE / 4];
171
172#if _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN
173 memcpy(in, block, sizeof(in));
174#else
175 for (a = 0; a < MD5_BLOCK_SIZE / 4; a++)
176 {
177 in[a] = (uint32_t)(
178 (uint32_t)(block[a * 4 + 0]) |
179 (uint32_t)(block[a * 4 + 1]) << 8 |
180 (uint32_t)(block[a * 4 + 2]) << 16 |
181 (uint32_t)(block[a * 4 + 3]) << 24);
182 }
183#endif
260 184
261 MD5Transform(ctx->buf, (uint32_t *) ctx->in); 185 a = state[0];
262 byteReverse((unsigned char *) ctx->buf, 4); 186 b = state[1];
263 memcpy(digest, ctx->buf, 16); 187 c = state[2];
264 memset(ctx, 0, sizeof(struct MD5Context)); /* In case it's sensitive */ 188 d = state[3];
189
190 MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
191 MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
192 MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
193 MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
194 MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
195 MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
196 MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
197 MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
198 MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
199 MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
200 MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
201 MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
202 MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
203 MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
204 MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
205 MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
206
207 MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
208 MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
209 MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
210 MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
211 MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
212 MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
213 MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
214 MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
215 MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
216 MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
217 MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
218 MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
219 MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
220 MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
221 MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
222 MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
223
224 MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
225 MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
226 MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
227 MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
228 MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
229 MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
230 MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
231 MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
232 MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
233 MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
234 MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
235 MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
236 MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
237 MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
238 MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
239 MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
240
241 MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
242 MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
243 MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
244 MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
245 MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
246 MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
247 MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
248 MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
249 MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
250 MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
251 MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
252 MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
253 MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
254 MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
255 MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
256 MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
257
258 state[0] += a;
259 state[1] += b;
260 state[2] += c;
261 state[3] += d;
265} 262}
266 263
267/* end of md5.c */ 264/* end of md5.c */
diff --git a/src/microhttpd/md5.h b/src/microhttpd/md5.h
index 5e77774c..ad1151e9 100644
--- a/src/microhttpd/md5.h
+++ b/src/microhttpd/md5.h
@@ -15,38 +15,50 @@
15 * will fill a supplied 16-byte array with the digest. 15 * will fill a supplied 16-byte array with the digest.
16 */ 16 */
17 17
18/* Brutally hacked by John Walker back from ANSI C to K&R (no 18#ifndef MHD_MD5_H
19 prototypes) to maintain the tradition that Netfone will compile 19#define MHD_MD5_H
20 with Sun's original "cc". */
21
22#ifndef MD5_H
23#define MD5_H
24 20
25#include "platform.h" 21#include "platform.h"
26#ifdef WORDS_BIGENDIAN
27#define HIGHFIRST
28#endif
29 22
30#define MD5_DIGEST_SIZE 16 23#define MD5_BLOCK_SIZE 64
24#define MD5_DIGEST_SIZE 16
25#define MD5_DIGEST_STRING_LENGTH (MD5_DIGEST_SIZE * 2 + 1)
31 26
32struct MD5Context 27struct MD5Context
33{ 28{
34 uint32_t buf[4]; 29 uint32_t state[4]; /* state */
35 uint32_t bits[2]; 30 uint64_t count; /* number of bits, mod 2^64 */
36 unsigned char in[64]; 31 uint8_t buffer[MD5_BLOCK_SIZE]; /* input buffer */
37}; 32};
38 33
34/*
35 * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
36 * initialization constants.
37 */
38void MD5Init(struct MD5Context *ctx);
39
40/*
41 * Update context to reflect the concatenation of another buffer full
42 * of bytes.
43 */
44void MD5Update(struct MD5Context *ctx, const unsigned char *input, size_t len);
39 45
40void 46/*
41MD5Init(struct MD5Context *ctx); 47 * Pad pad to 64-byte boundary with the bit pattern
48 * 1 0* (64-bit count of bits processed, MSB-first)
49 */
50void MD5Pad(struct MD5Context *ctx);
42 51
43void 52/*
44MD5Update(struct MD5Context *ctx, 53 * Final wrapup--call MD5Pad, fill in digest and zero out ctx.
45 const void *buf, 54 */
46 unsigned len); 55void MD5Final(unsigned char digest[MD5_DIGEST_SIZE], struct MD5Context *ctx);
47 56
48void 57/*
49MD5Final(unsigned char digest[MD5_DIGEST_SIZE], 58 * The core of the MD5 algorithm, this alters an existing MD5 hash to
50 struct MD5Context *ctx); 59 * reflect the addition of 16 longwords of new data. MD5Update blocks
60 * the data and converts bytes into longwords for this routine.
61 */
62void MD5Transform(uint32_t state[4], const uint8_t block[MD5_BLOCK_SIZE]);
51 63
52#endif /* !MD5_H */ 64#endif /* !MHD_MD5_H */