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