1/* 2 Unix SMB/Netbios implementation. 3 Version 1.9. 4 a implementation of MD4 designed for use in the SMB authentication protocol 5 Copyright (C) Andrew Tridgell 1997 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20*/ 21 22 23/* NOTE: This code makes no attempt to be fast! 24 25 It assumes that a int is at least 32 bits long 26*/ 27 28typedef unsigned int uint32; 29 30static uint32 A, B, C, D; 31 32static uint32 F(uint32 X, uint32 Y, uint32 Z) 33{ 34 return (X&Y) | ((~X)&Z); 35} 36 37static uint32 G(uint32 X, uint32 Y, uint32 Z) 38{ 39 return (X&Y) | (X&Z) | (Y&Z); 40} 41 42static uint32 H(uint32 X, uint32 Y, uint32 Z) 43{ 44 return X^Y^Z; 45} 46 47static uint32 lshift(uint32 x, int s) 48{ 49 x &= 0xFFFFFFFF; 50 return ((x<<s)&0xFFFFFFFF) | (x>>(32-s)); 51} 52 53#define ROUND1(a,b,c,d,k,s) a = lshift(a + F(b,c,d) + X[k], s) 54#define ROUND2(a,b,c,d,k,s) a = lshift(a + G(b,c,d) + X[k] + (uint32)0x5A827999,s) 55#define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + (uint32)0x6ED9EBA1,s) 56 57/* this applies md4 to 64 byte chunks */ 58static void mdfour64(uint32 *M) 59{ 60 int j; 61 uint32 AA, BB, CC, DD; 62 uint32 X[16]; 63 64 for (j=0;j<16;j++) 65 X[j] = M[j]; 66 67 AA = A; BB = B; CC = C; DD = D; 68 69 ROUND1(A,B,C,D, 0, 3); ROUND1(D,A,B,C, 1, 7); 70 ROUND1(C,D,A,B, 2, 11); ROUND1(B,C,D,A, 3, 19); 71 ROUND1(A,B,C,D, 4, 3); ROUND1(D,A,B,C, 5, 7); 72 ROUND1(C,D,A,B, 6, 11); ROUND1(B,C,D,A, 7, 19); 73 ROUND1(A,B,C,D, 8, 3); ROUND1(D,A,B,C, 9, 7); 74 ROUND1(C,D,A,B, 10, 11); ROUND1(B,C,D,A, 11, 19); 75 ROUND1(A,B,C,D, 12, 3); ROUND1(D,A,B,C, 13, 7); 76 ROUND1(C,D,A,B, 14, 11); ROUND1(B,C,D,A, 15, 19); 77 78 ROUND2(A,B,C,D, 0, 3); ROUND2(D,A,B,C, 4, 5); 79 ROUND2(C,D,A,B, 8, 9); ROUND2(B,C,D,A, 12, 13); 80 ROUND2(A,B,C,D, 1, 3); ROUND2(D,A,B,C, 5, 5); 81 ROUND2(C,D,A,B, 9, 9); ROUND2(B,C,D,A, 13, 13); 82 ROUND2(A,B,C,D, 2, 3); ROUND2(D,A,B,C, 6, 5); 83 ROUND2(C,D,A,B, 10, 9); ROUND2(B,C,D,A, 14, 13); 84 ROUND2(A,B,C,D, 3, 3); ROUND2(D,A,B,C, 7, 5); 85 ROUND2(C,D,A,B, 11, 9); ROUND2(B,C,D,A, 15, 13); 86 87 ROUND3(A,B,C,D, 0, 3); ROUND3(D,A,B,C, 8, 9); 88 ROUND3(C,D,A,B, 4, 11); ROUND3(B,C,D,A, 12, 15); 89 ROUND3(A,B,C,D, 2, 3); ROUND3(D,A,B,C, 10, 9); 90 ROUND3(C,D,A,B, 6, 11); ROUND3(B,C,D,A, 14, 15); 91 ROUND3(A,B,C,D, 1, 3); ROUND3(D,A,B,C, 9, 9); 92 ROUND3(C,D,A,B, 5, 11); ROUND3(B,C,D,A, 13, 15); 93 ROUND3(A,B,C,D, 3, 3); ROUND3(D,A,B,C, 11, 9); 94 ROUND3(C,D,A,B, 7, 11); ROUND3(B,C,D,A, 15, 15); 95 96 A += AA; B += BB; C += CC; D += DD; 97 98 A &= 0xFFFFFFFF; B &= 0xFFFFFFFF; 99 C &= 0xFFFFFFFF; D &= 0xFFFFFFFF; 100 101 for (j=0;j<16;j++) 102 X[j] = 0; 103} 104 105static void copy64(uint32 *M, unsigned char *in) 106{ 107 int i; 108 109 for (i=0;i<16;i++) 110 M[i] = (in[i*4+3]<<24) | (in[i*4+2]<<16) | 111 (in[i*4+1]<<8) | (in[i*4+0]<<0); 112} 113 114static void copy4(unsigned char *out,uint32 x) 115{ 116 out[0] = x&0xFF; 117 out[1] = (x>>8)&0xFF; 118 out[2] = (x>>16)&0xFF; 119 out[3] = (x>>24)&0xFF; 120} 121 122/* produce a md4 message digest from data of length n bytes */ 123void mdfour(unsigned char *out, unsigned char *in, int n) 124{ 125 unsigned char buf[128]; 126 uint32 M[16]; 127 uint32 b = n * 8; 128 int i; 129 130 A = 0x67452301; 131 B = 0xefcdab89; 132 C = 0x98badcfe; 133 D = 0x10325476; 134 135 while (n > 64) { 136 copy64(M, in); 137 mdfour64(M); 138 in += 64; 139 n -= 64; 140 } 141 142 for (i=0;i<128;i++) 143 buf[i] = 0; 144 memcpy(buf, in, n); 145 buf[n] = 0x80; 146 147 if (n <= 55) { 148 copy4(buf+56, b); 149 copy64(M, buf); 150 mdfour64(M); 151 } else { 152 copy4(buf+120, b); 153 copy64(M, buf); 154 mdfour64(M); 155 copy64(M, buf+64); 156 mdfour64(M); 157 } 158 159 for (i=0;i<128;i++) 160 buf[i] = 0; 161 copy64(M, buf); 162 163 copy4(out, A); 164 copy4(out+4, B); 165 copy4(out+8, C); 166 copy4(out+12, D); 167 168 A = B = C = D = 0; 169} 170 171 172