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