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