5762853 [rkeene@sledge /home/rkeene/devel/backuppcd/all/backuppcd-200601171056]$ cat -n md4.c
  1 /* MD4C.C - RSA Data Security, Inc., MD4 message-digest algorithm
  2  */
  3 
  4 /* Copyright (C) 1990-2, RSA Data Security, Inc. All rights reserved.
  5 
  6    License to copy and use this software is granted provided that it
  7    is identified as the "RSA Data Security, Inc. MD4 Message-Digest
  8    Algorithm" in all material mentioning or referencing this software
  9    or this function.
 10 
 11    License is also granted to make and use derivative works provided
 12    that such works are identified as "derived from the RSA Data
 13    Security, Inc. MD4 Message-Digest Algorithm" in all material
 14    mentioning or referencing the derived work.
 15 
 16    RSA Data Security, Inc. makes no representations concerning either
 17    the merchantability of this software or the suitability of this
 18    software for any particular purpose. It is provided "as is"
 19    without express or implied warranty of any kind.
 20 
 21    These notices must be retained in any copies of any part of this
 22    documentation and/or software.
 23  */
 24 
 25 #include "md4.h"
 26 
 27 /* Constants for MD4Transform routine.
 28  */
 29 #define S11 3
 30 #define S12 7
 31 #define S13 11
 32 #define S14 19
 33 #define S21 3
 34 #define S22 5
 35 #define S23 9
 36 #define S24 13
 37 #define S31 3
 38 #define S32 9
 39 #define S33 11
 40 #define S34 15
 41 
 42 static void MD4Transform(uint32_t [4], unsigned char [64]);
 43 static void Encode(unsigned char *, uint32_t *, unsigned int);
 44 static void Decode(uint32_t *, unsigned char *, unsigned int);
 45 
 46 static unsigned char PADDING[64] = {
 47   0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 48   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 49   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 50 };
 51 
 52 /* F, G and H are basic MD4 functions.
 53  */
 54 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
 55 #define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
 56 #define H(x, y, z) ((x) ^ (y) ^ (z))
 57 
 58 /* ROTATE_LEFT rotates x left n bits.
 59  */
 60 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
 61 
 62 /* FF, GG and HH are transformations for rounds 1, 2 and 3 */
 63 /* Rotation is separate from addition to prevent recomputation */
 64 #define FF(a, b, c, d, x, s) { \
 65     (a) += F ((b), (c), (d)) + (x); \
 66     (a) = ROTATE_LEFT ((a), (s)); \
 67   }
 68 #define GG(a, b, c, d, x, s) { \
 69     (a) += G ((b), (c), (d)) + (x) + (uint32_t)0x5a827999; \
 70     (a) = ROTATE_LEFT ((a), (s)); \
 71   }
 72 #define HH(a, b, c, d, x, s) { \
 73     (a) += H ((b), (c), (d)) + (x) + (uint32_t)0x6ed9eba1; \
 74     (a) = ROTATE_LEFT ((a), (s)); \
 75   }
 76 
 77 /* MD4 initialization. Begins an MD4 operation, writing a new context.
 78  */
 79 void rsaref_MD4Init (context)
 80 rsaref_MD4_CTX *context;                                        /* context */
 81 {
 82   context->count[0] = context->count[1] = 0;
 83 
 84   /* Load magic initialization constants.
 85    */
 86   context->state[0] = 0x67452301;
 87   context->state[1] = 0xefcdab89;
 88   context->state[2] = 0x98badcfe;
 89   context->state[3] = 0x10325476;
 90 }
 91 
 92 /* MD4 block update operation. Continues an MD4 message-digest
 93      operation, processing another message block, and updating the
 94      context.
 95  */
 96 void rsaref_MD4Update (context, input, inputLen)
 97 rsaref_MD4_CTX *context;                                        /* context */
 98 unsigned char *input;                                /* input block */
 99 unsigned int inputLen;                     /* length of input block */
100 {
101   unsigned int i, index, partLen;
102 
103   /* Compute number of bytes mod 64 */
104   index = (unsigned int)((context->count[0] >> 3) & 0x3F);
105   /* Update number of bits */
106   if ((context->count[0] += ((uint32_t)inputLen << 3))
107       < ((uint32_t)inputLen << 3))
108     context->count[1]++;
109   context->count[1] += ((uint32_t)inputLen >> 29);
110 
111   partLen = 64 - index;
112 
113   /* Transform as many times as possible.
114    */
115   if (inputLen >= partLen) {
116     memcpy
117       ((unsigned char *)&context->buffer[index], (unsigned char *)input, partLen);
118     MD4Transform (context->state, context->buffer);
119 
120     for (i = partLen; i + 63 < inputLen; i += 64)
121       MD4Transform (context->state, &input[i]);
122 
123     index = 0;
124   }
125   else
126     i = 0;
127 
128   /* Buffer remaining input */
129   memcpy
130     ((unsigned char *)&context->buffer[index], (unsigned char *)&input[i],
131      inputLen-i);
132 }
133 
134 /* MD4 finalization. Ends an MD4 message-digest operation, writing the
135      the message digest and zeroizing the context.
136  */
137 void rsaref_MD4Final (digest, context)
138 unsigned char digest[16];                         /* message digest */
139 rsaref_MD4_CTX *context;                                        /* context */
140 {
141   unsigned char bits[8];
142   unsigned int index, padLen;
143 
144   /* Save number of bits */
145   Encode (bits, context->count, 8);
146 
147   /* Pad out to 56 mod 64.
148    */
149   index = (unsigned int)((context->count[0] >> 3) & 0x3f);
150   padLen = (index < 56) ? (56 - index) : (120 - index);
151   rsaref_MD4Update (context, PADDING, padLen);
152 
153   /* Append length (before padding) */
154   rsaref_MD4Update (context, bits, 8);
155   /* Store state in digest */
156   Encode (digest, context->state, 16);
157 
158   /* Zeroize sensitive information.
159    */
160   memset ((unsigned char *)context, 0, sizeof (*context));
161 }
162 
163 /* MD4 basic transformation. Transforms state based on block.
164  */
165 static void MD4Transform (state, block)
166 uint32_t state[4];
167 unsigned char block[64];
168 {
169   uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
170 
171   Decode (x, block, 64);
172 
173   /* Round 1 */
174   FF (a, b, c, d, x[ 0], S11); /* 1 */
175   FF (d, a, b, c, x[ 1], S12); /* 2 */
176   FF (c, d, a, b, x[ 2], S13); /* 3 */
177   FF (b, c, d, a, x[ 3], S14); /* 4 */
178   FF (a, b, c, d, x[ 4], S11); /* 5 */
179   FF (d, a, b, c, x[ 5], S12); /* 6 */
180   FF (c, d, a, b, x[ 6], S13); /* 7 */
181   FF (b, c, d, a, x[ 7], S14); /* 8 */
182   FF (a, b, c, d, x[ 8], S11); /* 9 */
183   FF (d, a, b, c, x[ 9], S12); /* 10 */
184   FF (c, d, a, b, x[10], S13); /* 11 */
185   FF (b, c, d, a, x[11], S14); /* 12 */
186   FF (a, b, c, d, x[12], S11); /* 13 */
187   FF (d, a, b, c, x[13], S12); /* 14 */
188   FF (c, d, a, b, x[14], S13); /* 15 */
189   FF (b, c, d, a, x[15], S14); /* 16 */
190 
191   /* Round 2 */
192   GG (a, b, c, d, x[ 0], S21); /* 17 */
193   GG (d, a, b, c, x[ 4], S22); /* 18 */
194   GG (c, d, a, b, x[ 8], S23); /* 19 */
195   GG (b, c, d, a, x[12], S24); /* 20 */
196   GG (a, b, c, d, x[ 1], S21); /* 21 */
197   GG (d, a, b, c, x[ 5], S22); /* 22 */
198   GG (c, d, a, b, x[ 9], S23); /* 23 */
199   GG (b, c, d, a, x[13], S24); /* 24 */
200   GG (a, b, c, d, x[ 2], S21); /* 25 */
201   GG (d, a, b, c, x[ 6], S22); /* 26 */
202   GG (c, d, a, b, x[10], S23); /* 27 */
203   GG (b, c, d, a, x[14], S24); /* 28 */
204   GG (a, b, c, d, x[ 3], S21); /* 29 */
205   GG (d, a, b, c, x[ 7], S22); /* 30 */
206   GG (c, d, a, b, x[11], S23); /* 31 */
207   GG (b, c, d, a, x[15], S24); /* 32 */
208 
209   /* Round 3 */
210   HH (a, b, c, d, x[ 0], S31); /* 33 */
211   HH (d, a, b, c, x[ 8], S32); /* 34 */
212   HH (c, d, a, b, x[ 4], S33); /* 35 */
213   HH (b, c, d, a, x[12], S34); /* 36 */
214   HH (a, b, c, d, x[ 2], S31); /* 37 */
215   HH (d, a, b, c, x[10], S32); /* 38 */
216   HH (c, d, a, b, x[ 6], S33); /* 39 */
217   HH (b, c, d, a, x[14], S34); /* 40 */
218   HH (a, b, c, d, x[ 1], S31); /* 41 */
219   HH (d, a, b, c, x[ 9], S32); /* 42 */
220   HH (c, d, a, b, x[ 5], S33); /* 43 */
221   HH (b, c, d, a, x[13], S34); /* 44 */
222   HH (a, b, c, d, x[ 3], S31); /* 45 */
223   HH (d, a, b, c, x[11], S32); /* 46 */
224   HH (c, d, a, b, x[ 7], S33); /* 47 */
225   HH (b, c, d, a, x[15], S34); /* 48 */
226 
227   state[0] += a;
228   state[1] += b;
229   state[2] += c;
230   state[3] += d;
231 
232   /* Zeroize sensitive information.
233    */
234   memset ((unsigned char *)x, 0, sizeof (x));
235 }
236 
237 /* Encodes input (uint32_t) into output (unsigned char). Assumes len is
238      a multiple of 4.
239  */
240 static void Encode (output, input, len)
241 unsigned char *output;
242 uint32_t *input;
243 unsigned int len;
244 {
245   unsigned int i, j;
246 
247   for (i = 0, j = 0; j < len; i++, j += 4) {
248     output[j] = (unsigned char)(input[i] & 0xff);
249     output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
250     output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
251     output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
252   }
253 }
254 
255 /* Decodes input (unsigned char) into output (uint32_t). Assumes len is
256      a multiple of 4.
257  */
258 static void Decode (output, input, len)
259 
260 uint32_t *output;
261 unsigned char *input;
262 unsigned int len;
263 {
264   unsigned int i, j;
265 
266   for (i = 0, j = 0; j < len; i++, j += 4)
267     output[i] = ((uint32_t)input[j]) | (((uint32_t)input[j+1]) << 8) |
268       (((uint32_t)input[j+2]) << 16) | (((uint32_t)input[j+3]) << 24);
269 }
5762854 [rkeene@sledge /home/rkeene/devel/backuppcd/all/backuppcd-200601171056]$

Click here to go back to the directory listing.
Click here to download this file.
last modified: 2005-08-19 07:02:53