1 /*@ S-nail - a mail user agent derived from Berkeley Mail.
2 *@ RFC 1321 derived MD5 algorithm implementation.
3 *@ This is included by nailfuns.h if 'HAVE_MD5 && !HAVE_XSSL_MD5',
4 *@ and contains MD5.H as well as MD5C.C from the RFC.
6 * Copyright (c) 2000-2004 Gunnar Ritter, Freiburg i. Br., Germany.
7 * Copyright (c) 2012 - 2017 Steffen (Daode) Nurpmeso <steffen@sdaoden.eu>.
10 /* MD5.H - header file for MD5C.C
12 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
15 License to copy and use this software is granted provided that it
16 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
17 Algorithm" in all material mentioning or referencing this software
20 License is also granted to make and use derivative works provided
21 that such works are identified as "derived from the RSA Data
22 Security, Inc. MD5 Message-Digest Algorithm" in all material
23 mentioning or referencing the derived work.
25 RSA Data Security, Inc. makes no representations concerning either
26 the merchantability of this software or the suitability of this
27 software for any particular purpose. It is provided "as is"
28 without express or implied warranty of any kind.
30 These notices must be retained in any copies of any part of this
31 documentation and/or software.
35 * This version of MD5 has been changed such that any unsigned type with
36 * at least 32 bits is acceptable. This is important e.g. for Cray vector
37 * machines which provide only 64-bit integers.
39 typedef unsigned long md5_type
;
42 md5_type state
[4]; /* state (ABCD) */
43 md5_type count
[2]; /* number of bits, modulo 2^64 (lsb first) */
44 unsigned char buffer
[64]; /* input buffer */
47 FL
void md5_init(md5_ctx
*);
48 FL
void md5_update(md5_ctx
*, unsigned char *, unsigned int);
49 FL
void md5_final(unsigned char[16], md5_ctx
*);
52 /* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
54 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
57 License to copy and use this software is granted provided that it
58 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
59 Algorithm" in all material mentioning or referencing this software
62 License is also granted to make and use derivative works provided
63 that such works are identified as "derived from the RSA Data
64 Security, Inc. MD5 Message-Digest Algorithm" in all material
65 mentioning or referencing the derived work.
67 RSA Data Security, Inc. makes no representations concerning either
68 the merchantability of this software or the suitability of this
69 software for any particular purpose. It is provided "as is"
70 without express or implied warranty of any kind.
72 These notices must be retained in any copies of any part of this
73 documentation and/or software.
78 #define UINT4B_MAX 0xFFFFFFFFul
80 /* Constants for MD5Transform routine.
99 static unsigned char PADDING
[64] = {
100 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
101 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
102 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
106 #define F(x,y,z) (((x) & (y)) | ((~(x)) & (z)))
107 #define G(x,y,z) (((x) & (z)) | ((y) & (~(z))))
110 /* As pointed out by Wei Dai <weidai@eskimo.com>, the above can be
111 * simplified to the code below. Wei attributes these optimizations
112 * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel.
114 #define F(b,c,d) ((((c) ^ (d)) & (b)) ^ (d))
115 #define G(b,c,d) ((((b) ^ (c)) & (d)) ^ (c))
116 #define H(b,c,d) ((b) ^ (c) ^ (d))
117 #define I(b,c,d) (((~(d) & UINT4B_MAX) | (b)) ^ (c))
119 /* ROTATE_LEFT rotates x left n bits.
121 #define ROTATE_LEFT(x, n) ((((x) << (n)) & UINT4B_MAX) | ((x) >> (32 - (n))))
124 * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
125 * Rotation is separate from addition to prevent recomputation.
127 #define FF(a, b, c, d, x, s, ac) { \
128 (a) = ((a) + F(b, c, d) + (x) + ((ac) & UINT4B_MAX)) & UINT4B_MAX; \
129 (a) = ROTATE_LEFT((a), (s)); \
130 (a) = ((a) + (b)) & UINT4B_MAX; \
133 #define GG(a, b, c, d, x, s, ac) { \
134 (a) = ((a) + G(b, c, d) + (x) + ((ac) & UINT4B_MAX)) & UINT4B_MAX; \
135 (a) = ROTATE_LEFT((a), (s)); \
136 (a) = ((a) + (b)) & UINT4B_MAX; \
139 #define HH(a, b, c, d, x, s, ac) { \
140 (a) = ((a) + H(b, c, d) + (x) + ((ac) & UINT4B_MAX)) & UINT4B_MAX; \
141 (a) = ROTATE_LEFT((a), (s)); \
142 (a) = ((a) + (b)) & UINT4B_MAX; \
145 #define II(a, b, c, d, x, s, ac) { \
146 (a) = ((a) + I(b, c, d) + (x) + ((ac) & UINT4B_MAX)) & UINT4B_MAX; \
147 (a) = ROTATE_LEFT((a), (s)); \
148 (a) = ((a) + (b)) & UINT4B_MAX; \
151 static void * (* volatile _volatile_memset
)(void*, int, size_t) = &(memset
);
153 static void Encode(unsigned char *outp
, md5_type
*inp
, unsigned int len
);
154 static void Decode(md5_type
*outp
, unsigned char *inp
, unsigned int len
);
155 static void MD5Transform(md5_type state
[], unsigned char block
[]);
158 * Encodes input (md5_type) into output (unsigned char). Assumes len is
162 Encode(unsigned char *outp
, md5_type
*inp
, unsigned int len
)
166 for (i
= 0, j
= 0; j
< len
; i
++, j
+= 4) {
167 outp
[j
] = inp
[i
] & 0xff;
168 outp
[j
+1] = (inp
[i
] >> 8) & 0xff;
169 outp
[j
+2] = (inp
[i
] >> 16) & 0xff;
170 outp
[j
+3] = (inp
[i
] >> 24) & 0xff;
175 * Decodes input (unsigned char) into output (md5_type). Assumes len is
179 Decode(md5_type
*outp
, unsigned char *inp
, unsigned int len
)
183 for (i
= 0, j
= 0; j
< len
; i
++, j
+= 4)
184 outp
[i
] = ((md5_type
)inp
[j
] |
185 (md5_type
)inp
[j
+1] << 8 |
186 (md5_type
)inp
[j
+2] << 16 |
187 (md5_type
)inp
[j
+3] << 24) & UINT4B_MAX
;
190 /* MD5 basic transformation. Transforms state based on block. */
192 MD5Transform(md5_type state
[4], unsigned char block
[64])
194 md5_type a
= state
[0], b
= state
[1], c
= state
[2], d
= state
[3],
197 Decode(x
, block
, 64);
200 FF(a
, b
, c
, d
, x
[ 0], S11
, 0xd76aa478); /* 1 */
201 FF(d
, a
, b
, c
, x
[ 1], S12
, 0xe8c7b756); /* 2 */
202 FF(c
, d
, a
, b
, x
[ 2], S13
, 0x242070db); /* 3 */
203 FF(b
, c
, d
, a
, x
[ 3], S14
, 0xc1bdceee); /* 4 */
204 FF(a
, b
, c
, d
, x
[ 4], S11
, 0xf57c0faf); /* 5 */
205 FF(d
, a
, b
, c
, x
[ 5], S12
, 0x4787c62a); /* 6 */
206 FF(c
, d
, a
, b
, x
[ 6], S13
, 0xa8304613); /* 7 */
207 FF(b
, c
, d
, a
, x
[ 7], S14
, 0xfd469501); /* 8 */
208 FF(a
, b
, c
, d
, x
[ 8], S11
, 0x698098d8); /* 9 */
209 FF(d
, a
, b
, c
, x
[ 9], S12
, 0x8b44f7af); /* 10 */
210 FF(c
, d
, a
, b
, x
[10], S13
, 0xffff5bb1); /* 11 */
211 FF(b
, c
, d
, a
, x
[11], S14
, 0x895cd7be); /* 12 */
212 FF(a
, b
, c
, d
, x
[12], S11
, 0x6b901122); /* 13 */
213 FF(d
, a
, b
, c
, x
[13], S12
, 0xfd987193); /* 14 */
214 FF(c
, d
, a
, b
, x
[14], S13
, 0xa679438e); /* 15 */
215 FF(b
, c
, d
, a
, x
[15], S14
, 0x49b40821); /* 16 */
218 GG(a
, b
, c
, d
, x
[ 1], S21
, 0xf61e2562); /* 17 */
219 GG(d
, a
, b
, c
, x
[ 6], S22
, 0xc040b340); /* 18 */
220 GG(c
, d
, a
, b
, x
[11], S23
, 0x265e5a51); /* 19 */
221 GG(b
, c
, d
, a
, x
[ 0], S24
, 0xe9b6c7aa); /* 20 */
222 GG(a
, b
, c
, d
, x
[ 5], S21
, 0xd62f105d); /* 21 */
223 GG(d
, a
, b
, c
, x
[10], S22
, 0x2441453); /* 22 */
224 GG(c
, d
, a
, b
, x
[15], S23
, 0xd8a1e681); /* 23 */
225 GG(b
, c
, d
, a
, x
[ 4], S24
, 0xe7d3fbc8); /* 24 */
226 GG(a
, b
, c
, d
, x
[ 9], S21
, 0x21e1cde6); /* 25 */
227 GG(d
, a
, b
, c
, x
[14], S22
, 0xc33707d6); /* 26 */
228 GG(c
, d
, a
, b
, x
[ 3], S23
, 0xf4d50d87); /* 27 */
229 GG(b
, c
, d
, a
, x
[ 8], S24
, 0x455a14ed); /* 28 */
230 GG(a
, b
, c
, d
, x
[13], S21
, 0xa9e3e905); /* 29 */
231 GG(d
, a
, b
, c
, x
[ 2], S22
, 0xfcefa3f8); /* 30 */
232 GG(c
, d
, a
, b
, x
[ 7], S23
, 0x676f02d9); /* 31 */
233 GG(b
, c
, d
, a
, x
[12], S24
, 0x8d2a4c8a); /* 32 */
236 HH(a
, b
, c
, d
, x
[ 5], S31
, 0xfffa3942); /* 33 */
237 HH(d
, a
, b
, c
, x
[ 8], S32
, 0x8771f681); /* 34 */
238 HH(c
, d
, a
, b
, x
[11], S33
, 0x6d9d6122); /* 35 */
239 HH(b
, c
, d
, a
, x
[14], S34
, 0xfde5380c); /* 36 */
240 HH(a
, b
, c
, d
, x
[ 1], S31
, 0xa4beea44); /* 37 */
241 HH(d
, a
, b
, c
, x
[ 4], S32
, 0x4bdecfa9); /* 38 */
242 HH(c
, d
, a
, b
, x
[ 7], S33
, 0xf6bb4b60); /* 39 */
243 HH(b
, c
, d
, a
, x
[10], S34
, 0xbebfbc70); /* 40 */
244 HH(a
, b
, c
, d
, x
[13], S31
, 0x289b7ec6); /* 41 */
245 HH(d
, a
, b
, c
, x
[ 0], S32
, 0xeaa127fa); /* 42 */
246 HH(c
, d
, a
, b
, x
[ 3], S33
, 0xd4ef3085); /* 43 */
247 HH(b
, c
, d
, a
, x
[ 6], S34
, 0x4881d05); /* 44 */
248 HH(a
, b
, c
, d
, x
[ 9], S31
, 0xd9d4d039); /* 45 */
249 HH(d
, a
, b
, c
, x
[12], S32
, 0xe6db99e5); /* 46 */
250 HH(c
, d
, a
, b
, x
[15], S33
, 0x1fa27cf8); /* 47 */
251 HH(b
, c
, d
, a
, x
[ 2], S34
, 0xc4ac5665); /* 48 */
254 II(a
, b
, c
, d
, x
[ 0], S41
, 0xf4292244); /* 49 */
255 II(d
, a
, b
, c
, x
[ 7], S42
, 0x432aff97); /* 50 */
256 II(c
, d
, a
, b
, x
[14], S43
, 0xab9423a7); /* 51 */
257 II(b
, c
, d
, a
, x
[ 5], S44
, 0xfc93a039); /* 52 */
258 II(a
, b
, c
, d
, x
[12], S41
, 0x655b59c3); /* 53 */
259 II(d
, a
, b
, c
, x
[ 3], S42
, 0x8f0ccc92); /* 54 */
260 II(c
, d
, a
, b
, x
[10], S43
, 0xffeff47d); /* 55 */
261 II(b
, c
, d
, a
, x
[ 1], S44
, 0x85845dd1); /* 56 */
262 II(a
, b
, c
, d
, x
[ 8], S41
, 0x6fa87e4f); /* 57 */
263 II(d
, a
, b
, c
, x
[15], S42
, 0xfe2ce6e0); /* 58 */
264 II(c
, d
, a
, b
, x
[ 6], S43
, 0xa3014314); /* 59 */
265 II(b
, c
, d
, a
, x
[13], S44
, 0x4e0811a1); /* 60 */
266 II(a
, b
, c
, d
, x
[ 4], S41
, 0xf7537e82); /* 61 */
267 II(d
, a
, b
, c
, x
[11], S42
, 0xbd3af235); /* 62 */
268 II(c
, d
, a
, b
, x
[ 2], S43
, 0x2ad7d2bb); /* 63 */
269 II(b
, c
, d
, a
, x
[ 9], S44
, 0xeb86d391); /* 64 */
271 state
[0] = (state
[0] + a
) & UINT4B_MAX
;
272 state
[1] = (state
[1] + b
) & UINT4B_MAX
;
273 state
[2] = (state
[2] + c
) & UINT4B_MAX
;
274 state
[3] = (state
[3] + d
) & UINT4B_MAX
;
277 * Zeroize sensitive information.
279 (*_volatile_memset
)(x
, 0, sizeof x
);
283 * MD5 initialization. Begins an MD5 operation, writing a new context.
287 md5_ctx
*context
/* context */
290 context
->count
[0] = context
->count
[1] = 0;
292 * Load magic initialization constants.
294 context
->state
[0] = 0x67452301;
295 context
->state
[1] = 0xefcdab89;
296 context
->state
[2] = 0x98badcfe;
297 context
->state
[3] = 0x10325476;
301 * MD5 block update operation. Continues an MD5 message-digest
302 * operation, processing another message block, and updating the
307 md5_ctx
*context
, /* context */
308 unsigned char *input
, /* input block */
309 unsigned int inputLen
/* length of input block */
312 unsigned int i
, idx
, partLen
;
314 /* Compute number of bytes mod 64 */
315 idx
= context
->count
[0]>>3 & 0x3F;
317 /* Update number of bits */
318 if ((context
->count
[0] = (context
->count
[0] + (inputLen
<<3)) &
320 < ((inputLen
<< 3) & UINT4B_MAX
))
321 context
->count
[1] = (context
->count
[1] + 1) & UINT4B_MAX
;
322 context
->count
[1] = (context
->count
[1] + (inputLen
>> 29)) & UINT4B_MAX
;
327 * Transform as many times as possible.
329 if (inputLen
>= partLen
) {
330 memcpy(&context
->buffer
[idx
], input
, partLen
);
331 MD5Transform(context
->state
, context
->buffer
);
333 for (i
= partLen
; i
+ 63 < inputLen
; i
+= 64)
334 MD5Transform(context
->state
, &input
[i
]);
340 /* Buffer remaining input */
341 memcpy(&context
->buffer
[idx
], &input
[i
], inputLen
-i
);
345 * MD5 finalization. Ends an MD5 message-digest operation, writing the
346 * the message digest and zeroizing the context.
350 unsigned char digest
[16], /* message digest */
351 md5_ctx
*context
/* context */
354 unsigned char bits
[8];
355 unsigned int idx
, padLen
;
357 /* Save number of bits */
358 Encode(bits
, context
->count
, 8);
361 * Pad out to 56 mod 64.
363 idx
= context
->count
[0]>>3 & 0x3f;
364 padLen
= idx
< 56 ? 56 - idx
: 120 - idx
;
365 md5_update(context
, PADDING
, padLen
);
367 /* Append length (before padding) */
368 md5_update(context
, bits
, 8);
369 /* Store state in digest */
370 Encode(digest
, context
->state
, 16);
373 * Zeroize sensitive information.
375 (*_volatile_memset
)(context
, 0, sizeof *context
);
404 #endif /* n_MAIN_SOURCE */