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