2 * md4.c, copied from src/router/ppp/pppd to src/bcmcrypto for general use,
3 * with a few casts added to make it usable with a fussy compiler.
5 * ********************************************************************
6 * md4.c -- Implementation of MD4 Message Digest Algorithm **
7 * Updated: 2/16/90 by Ronald L. Rivest **
8 * (C) 1990 RSA Data Security, Inc. **
9 * ********************************************************************
11 * Copyright (C) 2010, Broadcom Corporation
12 * All Rights Reserved.
14 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
15 * the contents of this file may not be disclosed to third parties, copied
16 * or duplicated in any form, in whole or in part, without the prior
17 * written permission of Broadcom Corporation.
19 * $Id: md4.c,v 1.5 2006-06-14 21:07:54 Exp $
24 * -- Include md4.h in your program
25 * -- Declare an MDstruct MD to hold the state of the digest
27 * -- Initialize MD using MDbegin(&MD)
28 * -- For each full block (64 bytes) X you wish to process, call
29 * MD4Update(&MD,X,512)
30 * (512 is the number of bits in a full block.)
31 * -- For the last block (less than 64 bytes) you wish to process,
33 * where n is the number of bits in the partial block. A partial
34 * block terminates the computation, so every MD computation
35 * should terminate by processing a partial block, even if it
37 * -- The message digest is available in MD.buffer[0] ...
38 * MD.buffer[3]. (Least-significant byte of each word
39 * should be output first.)
40 * -- You can print out the digest using MDprint(&MD)
43 /* Implementation notes:
44 * This implementation assumes that ints are 32-bit quantities.
49 #include <bcmcrypto/md4.h>
55 /* Compile-time declarations of MD4 "magic constants". */
56 #define I0 0x67452301 /* Initial values for MD buffer */
60 #define C2 013240474631 /* round 2 constant = sqrt(2) in octal */
61 #define C3 015666365641 /* round 3 constant = sqrt(3) in octal */
62 /* C2 and C3 are from Knuth, The Art of Programming, Volume 2
63 * (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley.
67 #define fs1 3 /* round 1 shift amounts */
71 #define gs1 3 /* round 2 shift amounts */
75 #define hs1 3 /* round 3 shift amounts */
80 /* Compile-time macro declarations for MD4.
81 * Note: The "rot" operator uses the variable "tmp".
82 * It assumes tmp is declared as unsigned int, so that the >>
83 * operator will shift in zeros rather than extending the sign bit.
85 #define f(X, Y, Z) ((X & Y) | ((~X) & Z))
86 #define g(X, Y, Z) ((X & Y) | (X & Z) | (Y & Z))
87 #define h(X, Y, Z) (X ^ Y ^ Z)
88 #define rot(X, S) (tmp = X, (tmp << S) | (tmp >> (32 - S)))
89 #define ff(A, B, C, D, i, s) A = rot((A + f(B, C, D) + X[i]), s)
90 #define gg(A, B, C, D, i, s) A = rot((A + g(B, C, D) + X[i] + C2), s)
91 #define hh(A, B, C, D, i, s) A = rot((A + h(B, C, D) + X[i] + C3), s)
95 * Initialize message digest buffer MDp.
96 * This is a user-callable routine.
99 BCMROMFN(MD4Init
)(MD4_CTX
*MDp
)
106 for (i
= 0; i
< 8; i
++)
112 * Update message digest buffer MDp->buffer using 16-word data block X.
113 * Assumes all 16 words of X are full of data.
114 * Does not update MDp->count.
115 * This routine is not user-callable.
118 MDblock(MD4_CTX
*MDp
, unsigned char *Xb
)
120 register unsigned int tmp
, A
, B
, C
, D
;
124 for (i
= 0; i
< 16; ++i
) {
125 X
[i
] = Xb
[0] + (Xb
[1] << 8) + (Xb
[2] << 16) + (Xb
[3] << 24);
133 /* Update the message digest buffer */
134 ff(A
, B
, C
, D
, 0, fs1
); /* Round 1 */
135 ff(D
, A
, B
, C
, 1, fs2
);
136 ff(C
, D
, A
, B
, 2, fs3
);
137 ff(B
, C
, D
, A
, 3, fs4
);
138 ff(A
, B
, C
, D
, 4, fs1
);
139 ff(D
, A
, B
, C
, 5, fs2
);
140 ff(C
, D
, A
, B
, 6, fs3
);
141 ff(B
, C
, D
, A
, 7, fs4
);
142 ff(A
, B
, C
, D
, 8, fs1
);
143 ff(D
, A
, B
, C
, 9, fs2
);
144 ff(C
, D
, A
, B
, 10, fs3
);
145 ff(B
, C
, D
, A
, 11, fs4
);
146 ff(A
, B
, C
, D
, 12, fs1
);
147 ff(D
, A
, B
, C
, 13, fs2
);
148 ff(C
, D
, A
, B
, 14, fs3
);
149 ff(B
, C
, D
, A
, 15, fs4
);
150 gg(A
, B
, C
, D
, 0, gs1
); /* Round 2 */
151 gg(D
, A
, B
, C
, 4, gs2
);
152 gg(C
, D
, A
, B
, 8, gs3
);
153 gg(B
, C
, D
, A
, 12, gs4
);
154 gg(A
, B
, C
, D
, 1, gs1
);
155 gg(D
, A
, B
, C
, 5, gs2
);
156 gg(C
, D
, A
, B
, 9, gs3
);
157 gg(B
, C
, D
, A
, 13, gs4
);
158 gg(A
, B
, C
, D
, 2, gs1
);
159 gg(D
, A
, B
, C
, 6, gs2
);
160 gg(C
, D
, A
, B
, 10, gs3
);
161 gg(B
, C
, D
, A
, 14, gs4
);
162 gg(A
, B
, C
, D
, 3, gs1
);
163 gg(D
, A
, B
, C
, 7, gs2
);
164 gg(C
, D
, A
, B
, 11, gs3
);
165 gg(B
, C
, D
, A
, 15, gs4
);
166 hh(A
, B
, C
, D
, 0, hs1
); /* Round 3 */
167 hh(D
, A
, B
, C
, 8, hs2
);
168 hh(C
, D
, A
, B
, 4, hs3
);
169 hh(B
, C
, D
, A
, 12, hs4
);
170 hh(A
, B
, C
, D
, 2, hs1
);
171 hh(D
, A
, B
, C
, 10, hs2
);
172 hh(C
, D
, A
, B
, 6, hs3
);
173 hh(B
, C
, D
, A
, 14, hs4
);
174 hh(A
, B
, C
, D
, 1, hs1
);
175 hh(D
, A
, B
, C
, 9, hs2
);
176 hh(C
, D
, A
, B
, 5, hs3
);
177 hh(B
, C
, D
, A
, 13, hs4
);
178 hh(A
, B
, C
, D
, 3, hs1
);
179 hh(D
, A
, B
, C
, 11, hs2
);
180 hh(C
, D
, A
, B
, 7, hs3
);
181 hh(B
, C
, D
, A
, 15, hs4
);
188 /* MD4Update(MDp,X,count)
189 * Input: X -- a pointer to an array of unsigned characters.
190 * count -- the number of bits of X to use.
191 * (if not a multiple of 8, uses high bits of last byte.)
192 * Update MDp using the number of bits of X given by count.
193 * This is the basic input routine for an MD4 user.
194 * The routine completes the MD computation when count < 512, so
195 * every MD computation should end with one call to MD4Update with a
196 * count less than 512. A call with count 0 will be ignored if the
197 * MD has already been terminated (done != 0), so an extra call with
198 * count 0 can be given as a "courtesy close" to force termination
202 BCMROMFN(MD4Update
)(MD4_CTX
*MDp
, unsigned char *X
, unsigned int count
)
204 unsigned int i
, tmp
, bit
, byte
, mask
;
205 unsigned char XX
[64];
208 /* return with no error if this is a courtesy close with count
209 * zero and MDp->done is true.
211 if (count
== 0 && MDp
->done
) return;
212 /* check to see if MD is already done and report error */
217 /* Add count to MDp->count */
222 *p
++ = (unsigned char) tmp
;
228 /* Full block of data to handle */
230 } else if (count
> 512) {
231 /* Check for count too large */
234 /* partial block -- must be last block so finish up */
236 /* Find out how many bytes and residual bits there are */
239 /* Copy X into XX since we need to modify it */
240 for (i
= 0; i
<= byte
; i
++)
242 for (i
= byte
+ 1; i
< 64; i
++)
244 /* Add padding '1' bit and low-order zeros in last byte */
245 mask
= 1 << (7 - bit
);
246 XX
[byte
] = (XX
[byte
] | mask
) & ~(mask
- 1);
247 /* If room for bit count, finish up with this block */
249 for (i
= 0; i
< 8; i
++)
250 XX
[56 + i
] = MDp
->count
[i
];
253 /* need to do two blocks to finish up */
255 for (i
= 0; i
< 56; i
++)
257 for (i
= 0; i
< 8; i
++)
258 XX
[56 + i
] = MDp
->count
[i
];
261 /* Set flag saying we're done with MD computation */
267 * Finish up MD4 computation and return message digest.
270 BCMROMFN(MD4Final
)(unsigned char *buf
, MD4_CTX
*MD
)
275 MD4Update(MD
, NULL
, 0);
276 for (i
= 0; i
< 4; ++i
) {
278 for (j
= 0; j
< 4; ++j
) {
279 *buf
++ = (unsigned char) w
;