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