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