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