1/* 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. 4 * 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 * ******************************************************************** 10 * 11 * Copyright (C) 2015, Broadcom Corporation 12 * All Rights Reserved. 13 * 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. 18 * 19 * $Id: md4.c 241182 2011-02-17 21:50:03Z $ 20 */ 21 22/* 23 * To use MD4: 24 * -- Include md4.h in your program 25 * -- Declare an MDstruct MD to hold the state of the digest 26 * computation. 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, 32 * MD4Update(&MD,X,n) 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 36 * has n = 0. 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) 41 */ 42 43/* Implementation notes: 44 * This implementation assumes that ints are 32-bit quantities. 45 */ 46 47#include <typedefs.h> 48 49#include <bcmcrypto/md4.h> 50 51#ifndef BCMDRIVER 52#include <stdio.h> 53#endif 54 55/* Compile-time declarations of MD4 "magic constants". */ 56#define I0 0x67452301 /* Initial values for MD buffer */ 57#define I1 0xefcdab89 58#define I2 0x98badcfe 59#define I3 0x10325476 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. 64 * Table 2, page 660. 65 */ 66 67#define fs1 3 /* round 1 shift amounts */ 68#define fs2 7 69#define fs3 11 70#define fs4 19 71#define gs1 3 /* round 2 shift amounts */ 72#define gs2 5 73#define gs3 9 74#define gs4 13 75#define hs1 3 /* round 3 shift amounts */ 76#define hs2 9 77#define hs3 11 78#define hs4 15 79 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. 84 */ 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) 92 93 94/* MD4Init(MDp) 95 * Initialize message digest buffer MDp. 96 * This is a user-callable routine. 97 */ 98void 99BCMROMFN(MD4Init)(MD4_CTX *MDp) 100{ 101 int i; 102 MDp->buffer[0] = I0; 103 MDp->buffer[1] = I1; 104 MDp->buffer[2] = I2; 105 MDp->buffer[3] = I3; 106 for (i = 0; i < 8; i++) 107 MDp->count[i] = 0; 108 MDp->done = 0; 109} 110 111/* MDblock(MDp,X) 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. 116 */ 117static void 118MDblock(MD4_CTX *MDp, unsigned char *Xb) 119{ 120 register unsigned int tmp, A, B, C, D; 121 unsigned int X[16]; 122 int i; 123 124 for (i = 0; i < 16; ++i) { 125 X[i] = Xb[0] + (Xb[1] << 8) + (Xb[2] << 16) + (Xb[3] << 24); 126 Xb += 4; 127 } 128 129 A = MDp->buffer[0]; 130 B = MDp->buffer[1]; 131 C = MDp->buffer[2]; 132 D = MDp->buffer[3]; 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); 182 MDp->buffer[0] += A; 183 MDp->buffer[1] += B; 184 MDp->buffer[2] += C; 185 MDp->buffer[3] += D; 186} 187 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 199 * if desired. 200 */ 201void 202BCMROMFN(MD4Update)(MD4_CTX *MDp, unsigned char *X, unsigned int count) 203{ 204 unsigned int i, tmp, bit, byte, mask; 205 unsigned char XX[64]; 206 unsigned char *p; 207 208 /* return with no error if this is a courtesy close with count 209 * zero and MDp->done is true. 210 */ 211 if (count == 0 && MDp->done) return; 212 /* check to see if MD is already done and report error */ 213 if (MDp->done) { 214 return; 215 } 216 217 /* Add count to MDp->count */ 218 tmp = count; 219 p = MDp->count; 220 while (tmp) { 221 tmp += *p; 222 *p++ = (unsigned char) tmp; 223 tmp = tmp >> 8; 224 } 225 226 /* Process data */ 227 if (count == 512) { 228 /* Full block of data to handle */ 229 MDblock(MDp, X); 230 } else if (count > 512) { 231 /* Check for count too large */ 232 return; 233 } else { 234 /* partial block -- must be last block so finish up */ 235 236 /* Find out how many bytes and residual bits there are */ 237 byte = count >> 3; 238 bit = count & 7; 239 /* Copy X into XX since we need to modify it */ 240 for (i = 0; i <= byte; i++) 241 XX[i] = X[i]; 242 for (i = byte + 1; i < 64; i++) 243 XX[i] = 0; 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 */ 248 if (byte <= 55) { 249 for (i = 0; i < 8; i++) 250 XX[56 + i] = MDp->count[i]; 251 MDblock(MDp, XX); 252 } else { 253 /* need to do two blocks to finish up */ 254 MDblock(MDp, XX); 255 for (i = 0; i < 56; i++) 256 XX[i] = 0; 257 for (i = 0; i < 8; i++) 258 XX[56 + i] = MDp->count[i]; 259 MDblock(MDp, XX); 260 } 261 /* Set flag saying we're done with MD computation */ 262 MDp->done = 1; 263 } 264} 265 266/* 267 * Finish up MD4 computation and return message digest. 268 */ 269void 270BCMROMFN(MD4Final)(unsigned char *buf, MD4_CTX *MD) 271{ 272 int i, j; 273 unsigned int w; 274 275 MD4Update(MD, NULL, 0); 276 for (i = 0; i < 4; ++i) { 277 w = MD->buffer[i]; 278 for (j = 0; j < 4; ++j) { 279 *buf++ = (unsigned char) w; 280 w >>= 8; 281 } 282 } 283} 284 285/* 286 * End of md4.c 287 */ 288