diff --git a/packages/base/hash/md5.pp b/packages/base/hash/md5.pp
index 905627dc20..a553ddabe0 100644
--- a/packages/base/hash/md5.pp
+++ b/packages/base/hash/md5.pp
@@ -53,7 +53,6 @@ function MDString(const S: String; const Version: Cardinal): TMDDigest;
 function MDBuffer(var Buf; const BufLen: PtrUInt; const Version: Cardinal): TMDDigest;
 function MDFile(const Filename: String; const Version: Cardinal; const Bufsize: PtrUInt = DefBufSize): TMDDigest;
 function MDPrint(const Digest: TMDDigest): String;
-// based on an implementation by Matthias Fichtner
 function MDMatch(const Digest1, Digest2: TMDDigest): Boolean;
 
 implementation
@@ -364,15 +363,10 @@ end;
 
 function MDMatch(const Digest1, Digest2: TMDDigest): Boolean;
 var
-  I: Byte;
+  A: array[0..3] of Cardinal absolute Digest1;
+  B: array[0..3] of Cardinal absolute Digest2;
 begin
-  I := 0;
-  Result := True;
-  while Result and (I < 16) do
-  begin
-    Result := Digest1[I] = Digest2[I];
-    inc(I);
-  end;
+  Result := (A[0] = B[0]) and (A[1] = B[1]) and (A[2] = B[2]) and (A[3] = B[3]);
 end;
 
 end.
diff --git a/packages/base/hash/md5test.pp b/packages/base/hash/md5test.pp
index 864bcbdd57..a4b9db2e3e 100644
--- a/packages/base/hash/md5test.pp
+++ b/packages/base/hash/md5test.pp
@@ -17,7 +17,8 @@ program md5test;
 
 {$h+}
 
-uses md5;
+uses md5, ntlm;
+
 var
   I: byte;
 
@@ -33,10 +34,22 @@ const
     );
 
 begin
+  Writeln('Executing RFC 1320 test suite ...');
+  for I := 1 to 7 do
+    Writeln('MD4 ("',Suite[i],'") = ',MDPrint(MDString(Suite[I], 4)));
+  Writeln();
+  Writeln('md4file (50)  : ',MDPrint(MDFile('md5test.pp',4,50)));
+  Writeln('md4file (def) : ',MDPrint(MDFile('md5test.pp',4)));
+  Writeln;
+
   Writeln('Executing RFC 1321 test suite ...');
   for I := 1 to 7 do
     Writeln('MD5 ("',Suite[i],'") = ',MDPrint(MDString(Suite[I], 5)));
   Writeln();
-  Writeln('md5file (50)  : ',MDPrint(MDFile('md5test.pp',5,10)));
+  Writeln('md5file (50)  : ',MDPrint(MDFile('md5test.pp',5,50)));
   Writeln('md5file (def) : ',MDPrint(MDFile('md5test.pp',5)));
+  Writeln;
+
+  Writeln('nt-password   : ',MDPrint(NTGenerate('foobar')));
+  Writeln('lm-password   : ',MDPrint(LMGenerate('foobar')));
 end.
diff --git a/packages/base/hash/ntlm.pas b/packages/base/hash/ntlm.pas
index 742e893bfa..7da0b31cb5 100644
--- a/packages/base/hash/ntlm.pas
+++ b/packages/base/hash/ntlm.pas
@@ -20,23 +20,14 @@ unit ntlm;
 interface
 
 uses
-  Strings,
-  Math,
-  md5;
+  Math, Strings, md5;
 
-type
-  THash = array[0..15] of Byte;
 
-procedure nt_lm_owf_gen(const pwd: PChar; var nt_p16: THash; var lm_p16: THash);
-procedure hash_to_str(const h: THash; const str: PChar);
+function LMGenerate(const Password: PChar): TMDDigest;
+function NTGenerate(const Password: PChar): TMDDigest;
 
 implementation
 
-
-//
-// Ported from SAMBA/source/libsmb/smbdes.c
-//
-
 const
   perm1: array[0..55] of Byte = (
     57, 49, 41, 33, 25, 17,  9,
@@ -150,6 +141,7 @@ begin
     _out[i] := _in[p[i]-1];
 end;
 
+
 procedure lshift({in/out} const d: PByte; {in} const count: Integer; {in} const n: Integer);
 var
   _out  : array[0..63] of Byte;
@@ -161,6 +153,7 @@ begin
     d[i] := _out[i];
 end;
 
+
 procedure concat({out} const _out: PByte; {in} const _in1, _in2: PByte; {in} const l1, l2: Integer);
 var
   i: Integer;
@@ -171,6 +164,7 @@ begin
     _out[i+l1] := _in2[i];
 end;
 
+
 procedure mxor({out} const _out: PByte; {in} const _in1, _in2: PByte; {in} const n: Integer);
 var
   i: Integer;
@@ -179,6 +173,7 @@ begin
     _out[i] := _in1[i] xor _in2[i];
 end;
 
+
 procedure dohash({out} const _out: PByte; {in} const _in: PByte; {in} const key: PByte; {in} const forw: Boolean);
 var
   i     : Integer;
@@ -271,6 +266,7 @@ begin
   permute(_out, @rl[0], @perm6[0], 64);
 end;
 
+
 procedure str_to_key({in} const str: PByte; {out} const key: PByte);
 var
   i: Integer;
@@ -287,6 +283,7 @@ begin
     key[i] := key[i] shl 1;
 end;
 
+
 procedure smbhash({out} const _out: PByte; {in} const _in: PByte; {in} const key: PByte; {in} const forw: Boolean);
 var
   i     : Integer;
@@ -316,6 +313,7 @@ begin
   end;
 end;
 
+
 procedure E_P16({in} const p14: PByte; {out} const p16: PByte);
 const
   sp8: array[0..7] of Byte = ($4b, $47, $53, $21, $40, $23, $24, $25);
@@ -324,102 +322,52 @@ begin
   smbhash(@p16[8], @sp8[0], @p14[7], True);
 end;
 
-procedure E_P24({in} const p21: PByte; {in} const c8: PByte; {out} const p24: PByte);
+
+(*procedure E_P24({in} const p21: PByte; {in} const c8: PByte; {out} const p24: PByte);
 begin
   smbhash(@p24[0],  c8, @p21[0],  True);
   smbhash(@p24[8],  c8, @p21[7],  True);
   smbhash(@p24[16], c8, @p21[14], True);
-end;
+end;*)
 
 
-
-//
-// Ported from SAMBA/source/libsmb/smbencrypt.c
-//
-
-(*
- * Creates the MD4 Hash of the users password in NT UNICODE.
- *)
-
-procedure E_md4hash({in} const pwd: PChar; {out} const p16: PByte);
-var
-  len, pos: Integer;
-  wpwd  : array[0..255] of Byte;
-begin
-  FillChar(wpwd, Sizeof(wpwd), 0);
-
-  (* Password must be converted to NT unicode - null terminated *)
-  len := 0;
-  pos := 0;
-  while (len < 256) and (pwd[pos] <> #0) do
-  begin
-    wpwd[len] := byte(pwd[pos]);
-    inc(len);
-    wpwd[len] := 0;
-    inc(pos);
-  end;
-
-  PMDDigest(p16)^ := MDBuffer(wpwd[0], len, 4);
-
-  FillChar(wpwd, Sizeof(wpwd), 0);
-end;
-
-procedure E_deshash({in} const pwd: PChar; {out} const p16: PByte);
+function LMGenerate(const Password: PChar): TMDDigest;
 var
   dospwd: array[0..14] of Byte;
 begin
+  if not Assigned(Password) then
+    Exit;
+
   FillChar(dospwd, Sizeof(dospwd), 0);
 
   (* Password must be converted to DOS charset - null terminated, uppercase *)
-  StrLCopy(pchar(@dospwd[0]), pchar(@pwd[0]), Sizeof(dospwd)-1);
-  StrUpper(pchar(@dospwd[0]));
+  StrLCopy(PChar(@dospwd[0]), PChar(@Password[0]), SizeOf(dospwd)-1);
+  StrUpper(PChar(@dospwd[0]));
 
-  (* ONly the first 14 chars are considered, password need not be null terminated *)
-  E_P16(@dospwd[0], p16);
+  (* Only the first 14 chars are considered, password need not be null terminated *)
+  E_P16(@dospwd[0], @Result);
 
   FillChar(dospwd, Sizeof(dospwd), 0);
 end;
 
 
-(*
- * Does both the NT and LM owfs of a user's password
- *)
-
-procedure nt_lm_owf_gen({in} const pwd: PChar; {out} var nt_p16: THash; {out} var lm_p16: THash);
+function NTGenerate(const Password: PChar): TMDDigest;
 var
-  passwd: array[0..513] of Char;
+  pos: Integer;
+  wpwd: array[0..127] of WideChar;
 begin
-  FillChar(passwd, Sizeof(passwd), 0);
-  StrLCopy(passwd, pwd, sizeof(passwd)-1);
+  if not Assigned(Password) then
+    Exit;
 
-  (* Calculate the MD4 hash (NT compatible) of the password *)
-  FillChar(nt_p16, Sizeof(nt_p16), 0);
-  E_md4hash(@passwd[0], @nt_p16[0]);
-
-  (* Calculate the SMB (lanman) hash functions of the password *)
-  FillChar(lm_p16, Sizeof(lm_p16), 0);
-  E_deshash(@passwd[0], @lm_p16[0]);
-
-  (* clear out local copy of user's password (just being paranoid). *)
-  FillChar(passwd, Sizeof(passwd), 0);
-end;
-
-procedure hash_to_str({in} const h: THash; {out} const str: PChar);
-const
-  to_hex: array[0..15] of char = ('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
-var
-  i: integer;
-  p: PChar;
-begin
-  p := str;
-  for i := 0 to 15 do
+  pos := 0;
+  while (pos < 128) and (Password[pos] <> #0) do
   begin
-     p^ := to_hex[(h[i] shr 4) and $F];
-     Inc(p);
-     p^ := to_hex[h[i] and $F];
-     inc(p);
+    wpwd[pos] := Password[pos];
+    inc(pos);
   end;
-  p^ := #0;
+
+  Result := MDBuffer(wpwd, 2*pos, 4);
+  FillChar(wpwd, Sizeof(wpwd), 0);
 end;
 
 end.