1 /* ppp-md4.c - MD4 Digest implementation 2 * 3 * Copyright (c) 2022 Eivind Nss. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in 14 * the documentation and/or other materials provided with the 15 * distribution. 16 * 17 * 3. The name(s) of the authors of this software must not be used to 18 * endorse or promote products derived from this software without 19 * prior written permission. 20 * 21 * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO 22 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 23 * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY 24 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 25 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 26 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 27 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 28 * 29 * Sections of this code holds different copyright information. 30 */ 31 #ifdef HAVE_CONFIG_H 32 #include "config.h" 33 #endif 34 35 #include <stdio.h> 36 #include <stdlib.h> 37 38 #include "crypto-priv.h" 39 40 41 #ifdef OPENSSL_HAVE_MD4 42 #include <openssl/evp.h> 43 44 #if OPENSSL_VERSION_NUMBER < 0x10100000L 45 #define EVP_MD_CTX_free EVP_MD_CTX_destroy 46 #define EVP_MD_CTX_new EVP_MD_CTX_create 47 #endif 48 49 50 static int md4_init(PPP_MD_CTX *ctx) 51 { 52 if (ctx) { 53 EVP_MD_CTX *mctx = EVP_MD_CTX_new(); 54 if (mctx) { 55 if (EVP_DigestInit(mctx, EVP_md4())) { 56 ctx->priv = mctx; 57 return 1; 58 } 59 EVP_MD_CTX_free(mctx); 60 } 61 } 62 return 0; 63 } 64 65 static int md4_update(PPP_MD_CTX *ctx, const void *data, size_t len) 66 { 67 if (EVP_DigestUpdate((EVP_MD_CTX*) ctx->priv, data, len)) { 68 return 1; 69 } 70 return 0; 71 } 72 73 static int md4_final(PPP_MD_CTX *ctx, unsigned char *out, unsigned int *len) 74 { 75 if (EVP_DigestFinal((EVP_MD_CTX*) ctx->priv, out, len)) { 76 return 1; 77 } 78 return 0; 79 } 80 81 static void md4_clean(PPP_MD_CTX *ctx) 82 { 83 if (ctx->priv) { 84 EVP_MD_CTX_free(ctx->priv); 85 ctx->priv = NULL; 86 } 87 } 88 89 90 #else // !OPENSSL_HAVE_MD4 91 92 #define TRUE 1 93 #define FALSE 0 94 95 /* 96 ** ******************************************************************** 97 ** md4.c -- Implementation of MD4 Message Digest Algorithm ** 98 ** Updated: 2/16/90 by Ronald L. Rivest ** 99 ** (C) 1990 RSA Data Security, Inc. ** 100 ** ******************************************************************** 101 */ 102 103 /* 104 ** To use MD4: 105 ** -- Include md4.h in your program 106 ** -- Declare an MDstruct MD to hold the state of the digest 107 ** computation. 108 ** -- Initialize MD using MDbegin(&MD) 109 ** -- For each full block (64 bytes) X you wish to process, call 110 ** MD4Update(&MD,X,512) 111 ** (512 is the number of bits in a full block.) 112 ** -- For the last block (less than 64 bytes) you wish to process, 113 ** MD4Update(&MD,X,n) 114 ** where n is the number of bits in the partial block. A partial 115 ** block terminates the computation, so every MD computation 116 ** should terminate by processing a partial block, even if it 117 ** has n = 0. 118 ** -- The message digest is available in MD.buffer[0] ... 119 ** MD.buffer[3]. (Least-significant byte of each word 120 ** should be output first.) 121 ** -- You can print out the digest using MDprint(&MD) 122 */ 123 124 /* Implementation notes: 125 ** This implementation assumes that ints are 32-bit quantities. 126 */ 127 128 /* MDstruct is the data structure for a message digest computation. 129 */ 130 typedef struct { 131 unsigned int buffer[4]; /* Holds 4-word result of MD computation */ 132 unsigned char count[8]; /* Number of bits processed so far */ 133 unsigned int done; /* Nonzero means MD computation finished */ 134 } MD4_CTX; 135 136 137 /* Compile-time declarations of MD4 "magic constants". 138 */ 139 #define I0 0x67452301 /* Initial values for MD buffer */ 140 #define I1 0xefcdab89 141 #define I2 0x98badcfe 142 #define I3 0x10325476 143 #define C2 013240474631 /* round 2 constant = sqrt(2) in octal */ 144 #define C3 015666365641 /* round 3 constant = sqrt(3) in octal */ 145 /* C2 and C3 are from Knuth, The Art of Programming, Volume 2 146 ** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley. 147 ** Table 2, page 660. 148 */ 149 150 #define fs1 3 /* round 1 shift amounts */ 151 #define fs2 7 152 #define fs3 11 153 #define fs4 19 154 #define gs1 3 /* round 2 shift amounts */ 155 #define gs2 5 156 #define gs3 9 157 #define gs4 13 158 #define hs1 3 /* round 3 shift amounts */ 159 #define hs2 9 160 #define hs3 11 161 #define hs4 15 162 163 /* Compile-time macro declarations for MD4. 164 ** Note: The "rot" operator uses the variable "tmp". 165 ** It assumes tmp is declared as unsigned int, so that the >> 166 ** operator will shift in zeros rather than extending the sign bit. 167 */ 168 #define f(X,Y,Z) ((X&Y) | ((~X)&Z)) 169 #define g(X,Y,Z) ((X&Y) | (X&Z) | (Y&Z)) 170 #define h(X,Y,Z) (X^Y^Z) 171 #define rot(X,S) (tmp=X,(tmp<<S) | (tmp>>(32-S))) 172 #define ff(A,B,C,D,i,s) A = rot((A + f(B,C,D) + X[i]),s) 173 #define gg(A,B,C,D,i,s) A = rot((A + g(B,C,D) + X[i] + C2),s) 174 #define hh(A,B,C,D,i,s) A = rot((A + h(B,C,D) + X[i] + C3),s) 175 176 /* MD4print(MDp) 177 ** Print message digest buffer MDp as 32 hexadecimal digits. 178 ** Order is from low-order byte of buffer[0] to high-order byte of 179 ** buffer[3]. 180 ** Each byte is printed with high-order hexadecimal digit first. 181 ** This is a user-callable routine. 182 */ 183 static void 184 MD4Print(MD4_CTX *MDp) 185 { 186 int i,j; 187 for (i=0;i<4;i++) 188 for (j=0;j<32;j=j+8) 189 printf("%02x",(MDp->buffer[i]>>j) & 0xFF); 190 } 191 192 /* MD4Init(MDp) 193 ** Initialize message digest buffer MDp. 194 ** This is a user-callable routine. 195 */ 196 static void 197 MD4Init(MD4_CTX *MDp) 198 { 199 int i; 200 MDp->buffer[0] = I0; 201 MDp->buffer[1] = I1; 202 MDp->buffer[2] = I2; 203 MDp->buffer[3] = I3; 204 for (i=0;i<8;i++) MDp->count[i] = 0; 205 MDp->done = 0; 206 } 207 208 /* MDblock(MDp,X) 209 ** Update message digest buffer MDp->buffer using 16-word data block X. 210 ** Assumes all 16 words of X are full of data. 211 ** Does not update MDp->count. 212 ** This routine is not user-callable. 213 */ 214 static void 215 MDblock(MD4_CTX *MDp, unsigned char *Xb) 216 { 217 register unsigned int tmp, A, B, C, D; 218 unsigned int X[16]; 219 int i; 220 221 for (i = 0; i < 16; ++i) { 222 X[i] = Xb[0] + (Xb[1] << 8) + (Xb[2] << 16) + (Xb[3] << 24); 223 Xb += 4; 224 } 225 226 A = MDp->buffer[0]; 227 B = MDp->buffer[1]; 228 C = MDp->buffer[2]; 229 D = MDp->buffer[3]; 230 /* Update the message digest buffer */ 231 ff(A , B , C , D , 0 , fs1); /* Round 1 */ 232 ff(D , A , B , C , 1 , fs2); 233 ff(C , D , A , B , 2 , fs3); 234 ff(B , C , D , A , 3 , fs4); 235 ff(A , B , C , D , 4 , fs1); 236 ff(D , A , B , C , 5 , fs2); 237 ff(C , D , A , B , 6 , fs3); 238 ff(B , C , D , A , 7 , fs4); 239 ff(A , B , C , D , 8 , fs1); 240 ff(D , A , B , C , 9 , fs2); 241 ff(C , D , A , B , 10 , fs3); 242 ff(B , C , D , A , 11 , fs4); 243 ff(A , B , C , D , 12 , fs1); 244 ff(D , A , B , C , 13 , fs2); 245 ff(C , D , A , B , 14 , fs3); 246 ff(B , C , D , A , 15 , fs4); 247 gg(A , B , C , D , 0 , gs1); /* Round 2 */ 248 gg(D , A , B , C , 4 , gs2); 249 gg(C , D , A , B , 8 , gs3); 250 gg(B , C , D , A , 12 , gs4); 251 gg(A , B , C , D , 1 , gs1); 252 gg(D , A , B , C , 5 , gs2); 253 gg(C , D , A , B , 9 , gs3); 254 gg(B , C , D , A , 13 , gs4); 255 gg(A , B , C , D , 2 , gs1); 256 gg(D , A , B , C , 6 , gs2); 257 gg(C , D , A , B , 10 , gs3); 258 gg(B , C , D , A , 14 , gs4); 259 gg(A , B , C , D , 3 , gs1); 260 gg(D , A , B , C , 7 , gs2); 261 gg(C , D , A , B , 11 , gs3); 262 gg(B , C , D , A , 15 , gs4); 263 hh(A , B , C , D , 0 , hs1); /* Round 3 */ 264 hh(D , A , B , C , 8 , hs2); 265 hh(C , D , A , B , 4 , hs3); 266 hh(B , C , D , A , 12 , hs4); 267 hh(A , B , C , D , 2 , hs1); 268 hh(D , A , B , C , 10 , hs2); 269 hh(C , D , A , B , 6 , hs3); 270 hh(B , C , D , A , 14 , hs4); 271 hh(A , B , C , D , 1 , hs1); 272 hh(D , A , B , C , 9 , hs2); 273 hh(C , D , A , B , 5 , hs3); 274 hh(B , C , D , A , 13 , hs4); 275 hh(A , B , C , D , 3 , hs1); 276 hh(D , A , B , C , 11 , hs2); 277 hh(C , D , A , B , 7 , hs3); 278 hh(B , C , D , A , 15 , hs4); 279 MDp->buffer[0] += A; 280 MDp->buffer[1] += B; 281 MDp->buffer[2] += C; 282 MDp->buffer[3] += D; 283 } 284 285 /* MD4Update(MDp,X,count) 286 ** Input: X -- a pointer to an array of unsigned characters. 287 ** count -- the number of bits of X to use. 288 ** (if not a multiple of 8, uses high bits of last byte.) 289 ** Update MDp using the number of bits of X given by count. 290 ** This is the basic input routine for an MD4 user. 291 ** The routine completes the MD computation when count < 512, so 292 ** every MD computation should end with one call to MD4Update with a 293 ** count less than 512. A call with count 0 will be ignored if the 294 ** MD has already been terminated (done != 0), so an extra call with 295 ** count 0 can be given as a "courtesy close" to force termination 296 ** if desired. 297 */ 298 static void 299 MD4Update(MD4_CTX *MDp, unsigned char *X, unsigned int count) 300 { 301 unsigned int i, tmp, bit, byte, mask; 302 unsigned char XX[64]; 303 unsigned char *p; 304 305 /* return with no error if this is a courtesy close with count 306 ** zero and MDp->done is true. 307 */ 308 if (count == 0 && MDp->done) return; 309 /* check to see if MD is already done and report error */ 310 if (MDp->done) 311 { printf("\nError: MD4Update MD already done."); return; } 312 313 /* Add count to MDp->count */ 314 tmp = count; 315 p = MDp->count; 316 while (tmp) 317 { tmp += *p; 318 *p++ = tmp; 319 tmp = tmp >> 8; 320 } 321 322 /* Process data */ 323 if (count == 512) 324 { /* Full block of data to handle */ 325 MDblock(MDp,X); 326 } 327 else if (count > 512) /* Check for count too large */ 328 { 329 printf("\nError: MD4Update called with illegal count value %u.", 330 count); 331 return; 332 } 333 else /* partial block -- must be last block so finish up */ 334 { 335 /* Find out how many bytes and residual bits there are */ 336 byte = count >> 3; 337 bit = count & 7; 338 /* Copy X into XX since we need to modify it */ 339 if (count) 340 for (i=0;i<=byte;i++) XX[i] = X[i]; 341 for (i=byte+1;i<64;i++) XX[i] = 0; 342 /* Add padding '1' bit and low-order zeros in last byte */ 343 mask = 1 << (7 - bit); 344 XX[byte] = (XX[byte] | mask) & ~( mask - 1); 345 /* If room for bit count, finish up with this block */ 346 if (byte <= 55) 347 { 348 for (i=0;i<8;i++) XX[56+i] = MDp->count[i]; 349 MDblock(MDp,XX); 350 } 351 else /* need to do two blocks to finish up */ 352 { 353 MDblock(MDp,XX); 354 for (i=0;i<56;i++) XX[i] = 0; 355 for (i=0;i<8;i++) XX[56+i] = MDp->count[i]; 356 MDblock(MDp,XX); 357 } 358 /* Set flag saying we're done with MD computation */ 359 MDp->done = 1; 360 } 361 } 362 363 /* 364 ** Finish up MD4 computation and return message digest. 365 */ 366 static void 367 MD4Final(unsigned char *buf, MD4_CTX *MD) 368 { 369 int i, j; 370 unsigned int w; 371 372 MD4Update(MD, NULL, 0); 373 for (i = 0; i < 4; ++i) { 374 w = MD->buffer[i]; 375 for (j = 0; j < 4; ++j) { 376 *buf++ = w; 377 w >>= 8; 378 } 379 } 380 } 381 382 /* 383 ** End of md4.c 384 ****************************(cut)***********************************/ 385 386 static int md4_init(PPP_MD_CTX *ctx) 387 { 388 if (ctx) { 389 MD4_CTX *mctx = calloc(1, sizeof(MD4_CTX)); 390 if (mctx) { 391 MD4Init(mctx); 392 ctx->priv = mctx; 393 return 1; 394 } 395 } 396 return 0; 397 } 398 399 static int md4_update(PPP_MD_CTX *ctx, const void *data, size_t len) 400 { 401 #if defined(__NetBSD__) 402 /* NetBSD uses the libc md4 routines which take bytes instead of bits */ 403 int mdlen = len; 404 #else 405 int mdlen = len * 8; 406 #endif 407 408 /* Internal MD4Update can take at most 64 bytes at a time */ 409 while (mdlen > 512) { 410 MD4Update((MD4_CTX*) ctx->priv, (unsigned char*) data, 512); 411 data += 64; 412 mdlen -= 512; 413 } 414 MD4Update((MD4_CTX*) ctx->priv, (unsigned char*) data, mdlen); 415 return 1; 416 } 417 418 static int md4_final(PPP_MD_CTX *ctx, unsigned char *out, unsigned int *len) 419 { 420 MD4Final(out, (MD4_CTX*) ctx->priv); 421 return 1; 422 } 423 424 static void md4_clean(PPP_MD_CTX *ctx) 425 { 426 if (ctx->priv) { 427 free(ctx->priv); 428 ctx->priv = NULL; 429 } 430 } 431 432 #endif 433 434 static PPP_MD ppp_md4 = { 435 .init_fn = md4_init, 436 .update_fn = md4_update, 437 .final_fn = md4_final, 438 .clean_fn = md4_clean, 439 }; 440 441 const PPP_MD *PPP_md4(void) 442 { 443 return &ppp_md4; 444 } 445