s/qmail 4.3.20
Next generation secure email transport
Loading...
Searching...
No Matches
md5c.c
Go to the documentation of this file.
1/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
2 */
3
4/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
5 rights reserved.
6
7 License to copy and use this software is granted provided that it
8 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
9 Algorithm" in all material mentioning or referencing this software
10 or this function.
11
12 License is also granted to make and use derivative works provided
13 that such works are identified as "derived from the RSA Data
14 Security, Inc. MD5 Message-Digest Algorithm" in all material
15 mentioning or referencing the derived work.
16
17 RSA Data Security, Inc. makes no representations concerning either
18 the merchantability of this software or the suitability of this
19 software for any particular purpose. It is provided "as is"
20 without express or implied warranty of any kind.
21
22 These notices must be retained in any copies of any part of this
23 documentation and/or software.
24 */
25
26/* Redone with current POSIX integer data types -- feh, Aug 2024 */
27
28#include "md5.h"
29#include <stdint.h>
30
31/* Constants for MD5Transform routine. */
32#define S11 7
33#define S12 12
34#define S13 17
35#define S14 22
36#define S21 5
37#define S22 9
38#define S23 14
39#define S24 20
40#define S31 4
41#define S32 11
42#define S33 16
43#define S34 23
44#define S41 6
45#define S42 10
46#define S43 15
47#define S44 21
48
49static void MD5Transform(uint32_t [4],unsigned char [64]);
50static void Encode(unsigned char *,uint32_t *,unsigned int);
51static void Decode(uint32_t *,unsigned char *,unsigned int);
52static void MD5_memcpy(unsigned char *,unsigned char *,unsigned int);
53static void MD5_memset(unsigned char *,int,unsigned int);
54
55static unsigned char PADDING[64] = {
56 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
57 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
58 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
59};
60
61/* F, G, H and I are basic MD5 functions. */
62#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
63#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
64#define H(x, y, z) ((x) ^ (y) ^ (z))
65#define I(x, y, z) ((y) ^ ((x) | (~z)))
66
67/* ROTATE_LEFT rotates x left n bits. */
68#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
69
70/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
71 Rotation is separate from addition to prevent recomputation. */
72
73#define FF(a, b, c, d, x, s, ac) { \
74 (a) += F ((b), (c), (d)) + (x) + (uint32_t)(ac); \
75 (a) = ROTATE_LEFT ((a), (s)); \
76 (a) += (b); \
77 }
78#define GG(a, b, c, d, x, s, ac) { \
79 (a) += G ((b), (c), (d)) + (x) + (uint32_t)(ac); \
80 (a) = ROTATE_LEFT ((a), (s)); \
81 (a) += (b); \
82 }
83#define HH(a, b, c, d, x, s, ac) { \
84 (a) += H ((b), (c), (d)) + (x) + (uint32_t)(ac); \
85 (a) = ROTATE_LEFT ((a), (s)); \
86 (a) += (b); \
87 }
88#define II(a, b, c, d, x, s, ac) { \
89 (a) += I ((b), (c), (d)) + (x) + (uint32_t)(ac); \
90 (a) = ROTATE_LEFT ((a), (s)); \
91 (a) += (b); \
92 }
93
94/* MD5 initialization. Begins an MD5 operation, writing a new context. */
95void MD5Init(MD5_CTX *context)
96{
97 context->count[0] = context->count[1] = 0;
98
99 /* Load magic initialization constants. */
100 context->state[0] = 0x67452301;
101 context->state[1] = 0xefcdab89;
102 context->state[2] = 0x98badcfe;
103 context->state[3] = 0x10325476;
104}
105
106/* MD5 block update operation. Continues an MD5 message-digest operation,
107 processing another message block, and updating the context. */
108
109void MD5Update(MD5_CTX *context,unsigned char *input, unsigned int inputLen)
110{
111 unsigned int i, index, partLen;
112
113 /* Compute number of bytes mod 64 */
114 index = (unsigned int)((context->count[0] >> 3) & 0x3F);
115
116 /* Update number of bits */
117 if ((context->count[0] += ((uint32_t)inputLen << 3))
118 < ((uint32_t)inputLen << 3))
119 context->count[1]++;
120 context->count[1] += ((uint32_t)inputLen >> 29);
121
122 partLen = 64 - index;
123
124 /* Transform as many times as possible. */
125 if (inputLen >= partLen) {
126 MD5_memcpy((unsigned char *)&context->buffer[index],(unsigned char *)input,partLen);
127 MD5Transform(context->state, context->buffer);
128
129 for (i = partLen; i + 63 < inputLen; i += 64)
130 MD5Transform (context->state, &input[i]);
131
132 index = 0;
133 }
134 else
135 i = 0;
136
137 /* Buffer remaining input */
138 MD5_memcpy ((unsigned char *)&context->buffer[index],(unsigned char *)&input[i],inputLen - i);
139}
140
141/* MD5 finalization. Ends an MD5 message-digest operation, writing the
142 the message digest and zeroizing the context. */
143
144void MD5Final(unsigned char digest[16],MD5_CTX *context)
145{
146 unsigned char bits[8];
147 unsigned int index, padLen;
148
149 /* Save number of bits */
150 Encode(bits, context->count, 8);
151
152 /* Pad out to 56 mod 64. */
153 index = (unsigned int)((context->count[0] >> 3) & 0x3f);
154 padLen = (index < 56) ? (56 - index) : (120 - index);
155 MD5Update (context, PADDING, padLen);
156
157 /* Append length (before padding) */
158 MD5Update (context, bits, 8);
159
160 /* Store state in digest */
161 Encode(digest, context->state, 16);
162
163 /* Zeroize sensitive information. */
164 MD5_memset ((unsigned char *)context, 0, sizeof (*context));
165}
166
167/* MD5 basic transformation. Transforms state based on block. */
168
169static void MD5Transform (uint32_t state[4], unsigned char block[64])
170{
171 uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
172
173 Decode (x,block,64);
174
175 /* Round 1 */
176 FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
177 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
178 FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
179 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
180 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
181 FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
182 FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
183 FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
184 FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
185 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
186 FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
187 FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
188 FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
189 FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
190 FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
191 FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
192
193 /* Round 2 */
194 GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
195 GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
196 GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
197 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
198 GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
199 GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
200 GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
201 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
202 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
203 GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
204 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
205 GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
206 GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
207 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
208 GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
209 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
210
211 /* Round 3 */
212 HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
213 HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
214 HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
215 HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
216 HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
217 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
218 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
219 HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
220 HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
221 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
222 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
223 HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
224 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
225 HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
226 HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
227 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
228
229 /* Round 4 */
230 II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
231 II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
232 II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
233 II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
234 II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
235 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
236 II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
237 II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
238 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
239 II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
240 II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
241 II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
242 II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
243 II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
244 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
245 II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
246
247 state[0] += a;
248 state[1] += b;
249 state[2] += c;
250 state[3] += d;
251
252 /* Zeroize sensitive information. */
253 MD5_memset((unsigned char *)x,0,sizeof (x));
254}
255
256/* Encodes input (uint32_t) into output (unsigned char).
257 Assumes len is a multiple of 4. */
258
259static void Encode(unsigned char *output,uint32_t *input,unsigned int len)
260{
261 unsigned int i, j;
262
263 for (i = 0, j = 0; j < len; i++, j += 4) {
264 output[j] = (unsigned char)(input[i] & 0xff);
265 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
266 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
267 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
268 }
269}
270
271/* Decodes input (unsigned char) into output (uint32_t).
272 Assumes len is a multiple of 4. */
273
274static void Decode(uint32_t *output,unsigned char *input,unsigned int len)
275{
276 unsigned int i, j;
277
278 for (i = 0, j = 0; j < len; i++, j += 4)
279 output[i] = ((uint32_t)input[j]) | (((uint32_t)input[j+1]) << 8) |
280 (((uint32_t)input[j+2]) << 16) | (((uint32_t)input[j+3]) << 24);
281}
282
283/* Note: Replace "for loop" with standard memcpy if possible. */
284
285static void MD5_memcpy(unsigned char * output,unsigned char * input,unsigned int len)
286{
287 unsigned int i;
288
289 for (i = 0; i < len; i++)
290 output[i] = input[i];
291}
292
293/* Note: Replace "for loop" with standard memset if possible. */
294
295static void MD5_memset(unsigned char * output,int value,unsigned int len)
296{
297 unsigned int i;
298
299 for (i = 0; i < len; i++)
300 ((char *)output)[i] = (char)value;
301}
buffer b
Definition: auto-gid.c:10
void c(char *, char *, char *, int, int, int)
Definition: install.c:67
void MD5Init(MD5_CTX *context)
Definition: md5c.c:95
#define FF(a, b, c, d, x, s, ac)
Definition: md5c.c:73
#define S24
Definition: md5c.c:39
#define S33
Definition: md5c.c:42
#define S32
Definition: md5c.c:41
#define S12
Definition: md5c.c:33
#define S42
Definition: md5c.c:45
#define S11
Definition: md5c.c:32
#define S43
Definition: md5c.c:46
#define S23
Definition: md5c.c:38
#define GG(a, b, c, d, x, s, ac)
Definition: md5c.c:78
#define S44
Definition: md5c.c:47
#define S14
Definition: md5c.c:35
#define HH(a, b, c, d, x, s, ac)
Definition: md5c.c:83
void MD5Final(unsigned char digest[16], MD5_CTX *context)
Definition: md5c.c:144
void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputLen)
Definition: md5c.c:109
#define S13
Definition: md5c.c:34
#define S41
Definition: md5c.c:44
#define S21
Definition: md5c.c:36
#define II(a, b, c, d, x, s, ac)
Definition: md5c.c:88
#define S22
Definition: md5c.c:37
#define S31
Definition: md5c.c:40
#define S34
Definition: md5c.c:43
int
Definition: qmail-mrtg.c:27
int j
Definition: qmail-send.c:926
struct del * d[CHANNELS]
Definition: qmail-send.c:726
Definition: md5.h:31
unsigned char buffer[64]
Definition: md5.h:34
uint32_t count[2]
Definition: md5.h:33
uint32_t state[4]
Definition: md5.h:32