md4c.c revision 314144
11539Srgrimes/* MD4C.C - RSA Data Security, Inc., MD4 message-digest algorithm
21539Srgrimes */
31539Srgrimes
41539Srgrimes#include <sys/cdefs.h>
51539Srgrimes__FBSDID("$FreeBSD: stable/10/lib/libmd/md4c.c 314144 2017-02-23 16:07:45Z avg $");
61539Srgrimes
71539Srgrimes/* Copyright (C) 1990-2, RSA Data Security, Inc. All rights reserved.
81539Srgrimes
91539Srgrimes   License to copy and use this software is granted provided that it
101539Srgrimes   is identified as the "RSA Data Security, Inc. MD4 Message-Digest
111539Srgrimes   Algorithm" in all material mentioning or referencing this software
121539Srgrimes   or this function.
131539Srgrimes
141539Srgrimes   License is also granted to make and use derivative works provided
151539Srgrimes   that such works are identified as "derived from the RSA Data
161539Srgrimes   Security, Inc. MD4 Message-Digest Algorithm" in all material
171539Srgrimes   mentioning or referencing the derived work.
181539Srgrimes
191539Srgrimes   RSA Data Security, Inc. makes no representations concerning either
201539Srgrimes   the merchantability of this software or the suitability of this
211539Srgrimes   software for any particular purpose. It is provided "as is"
221539Srgrimes   without express or implied warranty of any kind.
231539Srgrimes
241539Srgrimes   These notices must be retained in any copies of any part of this
251539Srgrimes   documentation and/or software.
261539Srgrimes */
271539Srgrimes
281539Srgrimes#include <sys/types.h>
291539Srgrimes#include <string.h>
301539Srgrimes#include "md4.h"
311539Srgrimes
321539Srgrimestypedef unsigned char *POINTER;
331539Srgrimestypedef const unsigned char *CONST_POINTER;
3451794Smarceltypedef u_int16_t UINT2;
351539Srgrimestypedef u_int32_t UINT4;
361539Srgrimes
379343Sbde#define PROTO_LIST(list) list
389343Sbde
391539Srgrimes/* Constants for MD4Transform routine.
401539Srgrimes */
41102227Smike#define S11 3
421539Srgrimes#define S12 7
431539Srgrimes#define S13 11
44104582Smike#define S14 19
45105107Smike#define S21 3
46105107Smike#define S22 5
47105107Smike#define S23 9
48105107Smike#define S24 13
491539Srgrimes#define S31 3
501539Srgrimes#define S32 9
5147289Speter#define S33 11
521539Srgrimes#define S34 15
531539Srgrimes
54105013Smikestatic void MD4Transform PROTO_LIST ((UINT4 [4], const unsigned char [64]));
55104582Smikestatic void Encode PROTO_LIST
56104582Smike  ((unsigned char *, UINT4 *, unsigned int));
57104582Smikestatic void Decode PROTO_LIST
58104582Smike  ((UINT4 *, const unsigned char *, unsigned int));
59104582Smike
60104582Smikestatic unsigned char PADDING[64] = {
611539Srgrimes  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6293032Simp  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
63104582Smike  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
64105013Smike};
65102227Smike
66104368Srobert/* F, G and H are basic MD4 functions.
67104368Srobert */
6893032Simp#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
6993032Simp#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
7093032Simp#define H(x, y, z) ((x) ^ (y) ^ (z))
7193032Simp
7293032Simp/* ROTATE_LEFT rotates x left n bits.
7393032Simp */
74104368Srobert#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
7593032Simp
76104989Smike/* FF, GG and HH are transformations for rounds 1, 2 and 3 */
77104582Smike/* Rotation is separate from addition to prevent recomputation */
7834319Sdufault#define FF(a, b, c, d, x, s) { \
79105013Smike    (a) += F ((b), (c), (d)) + (x); \
80151395Sdavidxu    (a) = ROTATE_LEFT ((a), (s)); \
81151318Sdavidxu  }
82105107Smike#define GG(a, b, c, d, x, s) { \
83104582Smike    (a) += G ((b), (c), (d)) + (x) + (UINT4)0x5a827999; \
84104368Srobert    (a) = ROTATE_LEFT ((a), (s)); \
85104582Smike  }
86104582Smike#define HH(a, b, c, d, x, s) { \
8734319Sdufault    (a) += H ((b), (c), (d)) + (x) + (UINT4)0x6ed9eba1; \
88105013Smike    (a) = ROTATE_LEFT ((a), (s)); \
89102227Smike  }
90104368Srobert
9193032Simp/* MD4 initialization. Begins an MD4 operation, writing a new context.
92104582Smike */
93104582Smikevoid MD4Init (context)
94105013SmikeMD4_CTX *context;                                        /* context */
95105013Smike{
96105013Smike  context->count[0] = context->count[1] = 0;
97105013Smike
98104582Smike  /* Load magic initialization constants.
99104582Smike   */
100105107Smike  context->state[0] = 0x67452301;
10193032Simp  context->state[1] = 0xefcdab89;
10293032Simp  context->state[2] = 0x98badcfe;
10393032Simp  context->state[3] = 0x10325476;
10493032Simp}
10593032Simp
106104582Smike/* MD4 block update operation. Continues an MD4 message-digest
1071539Srgrimes     operation, processing another message block, and updating the
1081539Srgrimes     context.
1099343Sbde */
110void MD4Update (context, in, inputLen)
111MD4_CTX *context;                                        /* context */
112const void *in;                                /* input block */
113unsigned int inputLen;                     /* length of input block */
114{
115  unsigned int i, idx, partLen;
116  const unsigned char *input = in;
117
118  /* Compute number of bytes mod 64 */
119  idx = (unsigned int)((context->count[0] >> 3) & 0x3F);
120  /* Update number of bits */
121  if ((context->count[0] += ((UINT4)inputLen << 3))
122      < ((UINT4)inputLen << 3))
123    context->count[1]++;
124  context->count[1] += ((UINT4)inputLen >> 29);
125
126  partLen = 64 - idx;
127  /* Transform as many times as possible.
128   */
129  if (inputLen >= partLen) {
130    memcpy
131      ((POINTER)&context->buffer[idx], (CONST_POINTER)input, partLen);
132    MD4Transform (context->state, context->buffer);
133
134    for (i = partLen; i + 63 < inputLen; i += 64)
135      MD4Transform (context->state, &input[i]);
136
137    idx = 0;
138  }
139  else
140    i = 0;
141
142  /* Buffer remaining input */
143  memcpy
144    ((POINTER)&context->buffer[idx], (CONST_POINTER)&input[i],
145     inputLen-i);
146}
147
148/* MD4 padding. */
149void MD4Pad (context)
150MD4_CTX *context;                                        /* context */
151{
152  unsigned char bits[8];
153  unsigned int idx, padLen;
154
155  /* Save number of bits */
156  Encode (bits, context->count, 8);
157
158  /* Pad out to 56 mod 64.
159   */
160  idx = (unsigned int)((context->count[0] >> 3) & 0x3f);
161  padLen = (idx < 56) ? (56 - idx) : (120 - idx);
162  MD4Update (context, PADDING, padLen);
163
164  /* Append length (before padding) */
165  MD4Update (context, bits, 8);
166}
167
168/* MD4 finalization. Ends an MD4 message-digest operation, writing the
169     the message digest and zeroizing the context.
170 */
171void MD4Final (digest, context)
172unsigned char digest[16];                         /* message digest */
173MD4_CTX *context;                                        /* context */
174{
175  /* Do padding */
176  MD4Pad (context);
177
178  /* Store state in digest */
179  Encode (digest, context->state, 16);
180
181  /* Zeroize sensitive information.
182   */
183  memset ((POINTER)context, 0, sizeof (*context));
184}
185
186/* MD4 basic transformation. Transforms state based on block.
187 */
188static void MD4Transform (state, block)
189UINT4 state[4];
190const unsigned char block[64];
191{
192  UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
193
194  Decode (x, block, 64);
195
196  /* Round 1 */
197  FF (a, b, c, d, x[ 0], S11); /* 1 */
198  FF (d, a, b, c, x[ 1], S12); /* 2 */
199  FF (c, d, a, b, x[ 2], S13); /* 3 */
200  FF (b, c, d, a, x[ 3], S14); /* 4 */
201  FF (a, b, c, d, x[ 4], S11); /* 5 */
202  FF (d, a, b, c, x[ 5], S12); /* 6 */
203  FF (c, d, a, b, x[ 6], S13); /* 7 */
204  FF (b, c, d, a, x[ 7], S14); /* 8 */
205  FF (a, b, c, d, x[ 8], S11); /* 9 */
206  FF (d, a, b, c, x[ 9], S12); /* 10 */
207  FF (c, d, a, b, x[10], S13); /* 11 */
208  FF (b, c, d, a, x[11], S14); /* 12 */
209  FF (a, b, c, d, x[12], S11); /* 13 */
210  FF (d, a, b, c, x[13], S12); /* 14 */
211  FF (c, d, a, b, x[14], S13); /* 15 */
212  FF (b, c, d, a, x[15], S14); /* 16 */
213
214  /* Round 2 */
215  GG (a, b, c, d, x[ 0], S21); /* 17 */
216  GG (d, a, b, c, x[ 4], S22); /* 18 */
217  GG (c, d, a, b, x[ 8], S23); /* 19 */
218  GG (b, c, d, a, x[12], S24); /* 20 */
219  GG (a, b, c, d, x[ 1], S21); /* 21 */
220  GG (d, a, b, c, x[ 5], S22); /* 22 */
221  GG (c, d, a, b, x[ 9], S23); /* 23 */
222  GG (b, c, d, a, x[13], S24); /* 24 */
223  GG (a, b, c, d, x[ 2], S21); /* 25 */
224  GG (d, a, b, c, x[ 6], S22); /* 26 */
225  GG (c, d, a, b, x[10], S23); /* 27 */
226  GG (b, c, d, a, x[14], S24); /* 28 */
227  GG (a, b, c, d, x[ 3], S21); /* 29 */
228  GG (d, a, b, c, x[ 7], S22); /* 30 */
229  GG (c, d, a, b, x[11], S23); /* 31 */
230  GG (b, c, d, a, x[15], S24); /* 32 */
231
232  /* Round 3 */
233  HH (a, b, c, d, x[ 0], S31); /* 33 */
234  HH (d, a, b, c, x[ 8], S32); /* 34 */
235  HH (c, d, a, b, x[ 4], S33); /* 35 */
236  HH (b, c, d, a, x[12], S34); /* 36 */
237  HH (a, b, c, d, x[ 2], S31); /* 37 */
238  HH (d, a, b, c, x[10], S32); /* 38 */
239  HH (c, d, a, b, x[ 6], S33); /* 39 */
240  HH (b, c, d, a, x[14], S34); /* 40 */
241  HH (a, b, c, d, x[ 1], S31); /* 41 */
242  HH (d, a, b, c, x[ 9], S32); /* 42 */
243  HH (c, d, a, b, x[ 5], S33); /* 43 */
244  HH (b, c, d, a, x[13], S34); /* 44 */
245  HH (a, b, c, d, x[ 3], S31); /* 45 */
246  HH (d, a, b, c, x[11], S32); /* 46 */
247  HH (c, d, a, b, x[ 7], S33); /* 47 */
248  HH (b, c, d, a, x[15], S34); /* 48 */
249
250  state[0] += a;
251  state[1] += b;
252  state[2] += c;
253  state[3] += d;
254
255  /* Zeroize sensitive information.
256   */
257  memset ((POINTER)x, 0, sizeof (x));
258}
259
260/* Encodes input (UINT4) into output (unsigned char). Assumes len is
261     a multiple of 4.
262 */
263static void Encode (output, input, len)
264unsigned char *output;
265UINT4 *input;
266unsigned int len;
267{
268  unsigned int i, j;
269
270  for (i = 0, j = 0; j < len; i++, j += 4) {
271    output[j] = (unsigned char)(input[i] & 0xff);
272    output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
273    output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
274    output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
275  }
276}
277
278/* Decodes input (unsigned char) into output (UINT4). Assumes len is
279     a multiple of 4.
280 */
281static void Decode (output, input, len)
282
283UINT4 *output;
284const unsigned char *input;
285unsigned int len;
286{
287  unsigned int i, j;
288
289  for (i = 0, j = 0; j < len; i++, j += 4)
290    output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
291      (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
292}
293
294#undef MD4Init
295__weak_reference(_libmd_MD4Init, MD4Init);
296#undef MD4Update
297__weak_reference(_libmd_MD4Update, MD4Update);
298#undef MD4Pad
299__weak_reference(_libmd_MD4Pad, MD4Pad);
300#undef MD4Final
301__weak_reference(_libmd_MD4Final, MD4Final);
302