1/*
2 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
3 * Use is subject to license terms.
4 */
5
6
7/*
8 *	lib/crypto/md4/md4.c
9 */
10
11/*
12 **********************************************************************
13 ** md4.c                                                            **
14 ** RSA Data Security, Inc. MD4 Message Digest Algorithm             **
15 ** Created: 2/17/90 RLR                                             **
16 ** Revised: 1/91 SRD,AJ,BSK,JT Reference C Version                  **
17 **********************************************************************
18 */
19
20/*
21 **********************************************************************
22 ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
23 **                                                                  **
24 ** License to copy and use this software is granted provided that   **
25 ** it is identified as the "RSA Data Security, Inc. MD4 Message     **
26 ** Digest Algorithm" in all material mentioning or referencing this **
27 ** software or this function.                                       **
28 **                                                                  **
29 ** License is also granted to make and use derivative works         **
30 ** provided that such works are identified as "derived from the RSA **
31 ** Data Security, Inc. MD4 Message Digest Algorithm" in all         **
32 ** material mentioning or referencing the derived work.             **
33 **                                                                  **
34 ** RSA Data Security, Inc. makes no representations concerning      **
35 ** either the merchantability of this software or the suitability   **
36 ** of this software for any particular purpose.  It is provided "as **
37 ** is" without express or implied warranty of any kind.             **
38 **                                                                  **
39 ** These notices must be retained in any copies of any part of this **
40 ** documentation and/or software.                                   **
41 **********************************************************************
42 */
43
44#include "k5-int.h"
45#include "rsa-md4.h"
46
47/* forward declaration */
48static void Transform (krb5_ui_4 *, krb5_ui_4 *);
49
50static const unsigned char PADDING[64] = {
51  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
56  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
59};
60
61/* F, G and H are basic MD4 functions: selection, majority, parity */
62#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
63#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
64#define H(x, y, z) ((x) ^ (y) ^ (z))
65
66/* ROTATE_LEFT rotates x left n bits */
67#define ROTATE_LEFT(x, n) ((((x) << (n)) & 0xffffffff) | ((x) >> (32-(n))))
68
69/* FF, GG and HH are MD4 transformations for rounds 1, 2 and 3 */
70/* Rotation is separate from addition to prevent recomputation */
71#define FF(a, b, c, d, x, s) \
72  {(a) += F ((b), (c), (d)) + (x); \
73   (a) &= 0xffffffff; \
74   (a) = ROTATE_LEFT ((a), (s));}
75#define GG(a, b, c, d, x, s) \
76  {(a) += G ((b), (c), (d)) + (x) + 013240474631UL; \
77   (a) &= 0xffffffff; \
78   (a) = ROTATE_LEFT ((a), (s));}
79#define HH(a, b, c, d, x, s) \
80  {(a) += H ((b), (c), (d)) + (x) + 015666365641UL; \
81   (a) &= 0xffffffff; \
82   (a) = ROTATE_LEFT ((a), (s));}
83
84void
85krb5_MD4Init (krb5_MD4_CTX *mdContext)
86{
87  mdContext->i[0] = mdContext->i[1] = (krb5_ui_4)0;
88
89  /* Load magic initialization constants.
90   */
91  mdContext->buf[0] = 0x67452301UL;
92  mdContext->buf[1] = 0xefcdab89UL;
93  mdContext->buf[2] = 0x98badcfeUL;
94  mdContext->buf[3] = 0x10325476UL;
95}
96
97void
98krb5_MD4Update (krb5_MD4_CTX *mdContext, const unsigned char *inBuf, unsigned int inLen)
99{
100  krb5_ui_4 in[16];
101  int mdi;
102  unsigned int i, ii;
103
104  /* compute number of bytes mod 64 */
105  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
106
107  /* update number of bits */
108  if ((mdContext->i[0] + ((krb5_ui_4)inLen << 3)) < mdContext->i[0])
109    mdContext->i[1]++;
110  mdContext->i[0] += ((krb5_ui_4)inLen << 3);
111  mdContext->i[1] += ((krb5_ui_4)inLen >> 29);
112
113  while (inLen--) {
114    /* add new character to buffer, increment mdi */
115    mdContext->in[mdi++] = *inBuf++;
116
117    /* transform if necessary */
118    if (mdi == 0x40) {
119      for (i = 0, ii = 0; i < 16; i++, ii += 4)
120        in[i] = (((krb5_ui_4)mdContext->in[ii+3]) << 24) |
121                (((krb5_ui_4)mdContext->in[ii+2]) << 16) |
122                (((krb5_ui_4)mdContext->in[ii+1]) << 8) |
123                ((krb5_ui_4)mdContext->in[ii]);
124      Transform (mdContext->buf, in);
125      mdi = 0;
126    }
127  }
128}
129
130void
131krb5_MD4Final (krb5_MD4_CTX *mdContext)
132{
133  krb5_ui_4 in[16];
134  int mdi;
135  unsigned int i, ii;
136  unsigned int padLen;
137
138  /* save number of bits */
139  in[14] = mdContext->i[0];
140  in[15] = mdContext->i[1];
141
142  /* compute number of bytes mod 64 */
143  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
144
145  /* pad out to 56 mod 64 */
146  padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
147  krb5_MD4Update (mdContext, PADDING, padLen);
148
149  /* append length in bits and transform */
150  for (i = 0, ii = 0; i < 14; i++, ii += 4)
151    in[i] = (((krb5_ui_4)mdContext->in[ii+3]) << 24) |
152            (((krb5_ui_4)mdContext->in[ii+2]) << 16) |
153            (((krb5_ui_4)mdContext->in[ii+1]) << 8) |
154            ((krb5_ui_4)mdContext->in[ii]);
155  Transform (mdContext->buf, in);
156
157
158  /* store buffer in digest */
159  for (i = 0, ii = 0; i < 4; i++, ii += 4) {
160    mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);
161    mdContext->digest[ii+1] =
162      (unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
163    mdContext->digest[ii+2] =
164      (unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
165    mdContext->digest[ii+3] =
166      (unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
167  }
168}
169
170/* Basic MD4 step. Transform buf based on in.
171 */
172static void Transform (krb5_ui_4 *buf, krb5_ui_4 *in)
173{
174  register krb5_ui_4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
175
176#ifdef CONFIG_SMALL
177  int i;
178#define ROTATE { krb5_ui_4 temp; temp = d, d = c, c = b, b = a, a = temp; }
179  for (i = 0; i < 16; i++) {
180      static const unsigned char round1consts[] = { 3, 7, 11, 19, };
181      FF (a, b, c, d, in[i], round1consts[i%4]); ROTATE;
182  }
183  for (i = 0; i < 16; i++) {
184      static const unsigned char round2indices[] = {
185	  0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15
186      };
187      static const unsigned char round2consts[] = { 3, 5, 9, 13 };
188      GG (a, b, c, d, in[round2indices[i]], round2consts[i%4]); ROTATE;
189  }
190  for (i = 0; i < 16; i++) {
191      static const unsigned char round3indices[] = {
192	  0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15
193      };
194      static const unsigned char round3consts[] = { 3, 9, 11, 15 };
195      HH (a, b, c, d, in[round3indices[i]], round3consts[i%4]); ROTATE;
196  }
197#else
198  /* Round 1 */
199  FF (a, b, c, d, in[ 0],  3);
200  FF (d, a, b, c, in[ 1],  7);
201  FF (c, d, a, b, in[ 2], 11);
202  FF (b, c, d, a, in[ 3], 19);
203  FF (a, b, c, d, in[ 4],  3);
204  FF (d, a, b, c, in[ 5],  7);
205  FF (c, d, a, b, in[ 6], 11);
206  FF (b, c, d, a, in[ 7], 19);
207  FF (a, b, c, d, in[ 8],  3);
208  FF (d, a, b, c, in[ 9],  7);
209  FF (c, d, a, b, in[10], 11);
210  FF (b, c, d, a, in[11], 19);
211  FF (a, b, c, d, in[12],  3);
212  FF (d, a, b, c, in[13],  7);
213  FF (c, d, a, b, in[14], 11);
214  FF (b, c, d, a, in[15], 19);
215
216  /* Round 2 */
217  GG (a, b, c, d, in[ 0],  3);
218  GG (d, a, b, c, in[ 4],  5);
219  GG (c, d, a, b, in[ 8],  9);
220  GG (b, c, d, a, in[12], 13);
221  GG (a, b, c, d, in[ 1],  3);
222  GG (d, a, b, c, in[ 5],  5);
223  GG (c, d, a, b, in[ 9],  9);
224  GG (b, c, d, a, in[13], 13);
225  GG (a, b, c, d, in[ 2],  3);
226  GG (d, a, b, c, in[ 6],  5);
227  GG (c, d, a, b, in[10],  9);
228  GG (b, c, d, a, in[14], 13);
229  GG (a, b, c, d, in[ 3],  3);
230  GG (d, a, b, c, in[ 7],  5);
231  GG (c, d, a, b, in[11],  9);
232  GG (b, c, d, a, in[15], 13);
233
234  /* Round 3 */
235  HH (a, b, c, d, in[ 0],  3);
236  HH (d, a, b, c, in[ 8],  9);
237  HH (c, d, a, b, in[ 4], 11);
238  HH (b, c, d, a, in[12], 15);
239  HH (a, b, c, d, in[ 2],  3);
240  HH (d, a, b, c, in[10],  9);
241  HH (c, d, a, b, in[ 6], 11);
242  HH (b, c, d, a, in[14], 15);
243  HH (a, b, c, d, in[ 1],  3);
244  HH (d, a, b, c, in[ 9],  9);
245  HH (c, d, a, b, in[ 5], 11);
246  HH (b, c, d, a, in[13], 15);
247  HH (a, b, c, d, in[ 3],  3);
248  HH (d, a, b, c, in[11],  9);
249  HH (c, d, a, b, in[ 7], 11);
250  HH (b, c, d, a, in[15], 15);
251#endif
252
253  buf[0] += a;
254  buf[1] += b;
255  buf[2] += c;
256  buf[3] += d;
257}
258
259/*
260 **********************************************************************
261 ** End of md4.c                                                     **
262 ******************************* (cut) ********************************
263 */
264