diff --git a/_test/cases/inc/auth_password.test.php b/_test/cases/inc/auth_password.test.php
index 77ee9eed3fd3e0b7a790b7d5efd706219c49afa0..140c7c23e75f2614c7a95b60543f35534a93f45d 100644
--- a/_test/cases/inc/auth_password.test.php
+++ b/_test/cases/inc/auth_password.test.php
@@ -16,6 +16,8 @@ class auth_password_test extends UnitTestCase {
         'mysql' => '4a1fa3780bd6fd55',
         'my411' => '*e5929347e25f82e19e4ebe92f1dc6b6e7c2dbd29',
         'kmd5'  => 'a579299436d7969791189acadd86fcb716',
+        'pmd5'  => '$P$abcdefgh1RC6Fd32heUzl7EYCG9uGw.',
+        'hmd5'  => '$H$abcdefgh1ZbJodHxmeXVAhEzTG7IAp.',
     );
 
 
@@ -39,6 +41,11 @@ class auth_password_test extends UnitTestCase {
         $this->assertTrue(auth_verifyPassword('foo','$1$$n1rTiFE0nRifwV/43bVon/'));
     }
 
+    function test_verifyPassword_fixedpmd5(){
+        $this->assertTrue(auth_verifyPassword('test12345','$P$9IQRaTwmfeRo7ud9Fh4E2PdI0S3r.L0'));
+        $this->assertTrue(auth_verifyPassword('test12345','$H$9IQRaTwmfeRo7ud9Fh4E2PdI0S3r.L0'));
+    }
+
 }
 
 //Setup VIM: ex: et ts=4 :
diff --git a/inc/auth.php b/inc/auth.php
index 83d1d41598c52ecebf878f7fb2fa724559bc9a83..5cdcec830f813425b94184b51eb2959bd52eb859 100644
--- a/inc/auth.php
+++ b/inc/auth.php
@@ -937,6 +937,8 @@ function act_resendpwd(){
  *   mysql - MySQL password (old method)
  *   my411 - MySQL 4.1.1 password
  *   kmd5  - Salted MD5 hashing as used by UNB
+ *   pmd5  - Salted multi iteration MD5 as used by Wordpress
+ *   hmd5  - Same as pmd5 but PhpBB3 flavour
  *
  * @author  Andreas Gohr <andi@splitbrain.org>
  * @return  string  The crypted password
@@ -1016,6 +1018,45 @@ function auth_cryptPassword($clear,$method='',$salt=null){
             $hash1 = strtolower(md5($key . md5($clear)));
             $hash2 = substr($hash1, 0, 16) . $key . substr($hash1, 16);
             return $hash2;
+        case 'hmd5':
+            $key = 'H';
+            // hmd5 is exactly the same as pmd5, but uses an H as identifier
+            // PhpBB3 uses it that way, so we just fall through here
+        case 'pmd5':
+            if(!$key) $key = 'P';
+            $itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
+            $iterc = $salt[0]; // pos 0 of salt is iteration count
+            $iter = strpos($itoa64,$iterc);
+            $iter = 1 << $iter;
+            $salt = substr($salt,1,8);
+
+            // iterate
+            $hash = md5($salt . $clear, true);
+            do {
+                $hash = md5($hash . $clear, true);
+            } while (--$iter);
+
+            // encode
+            $output = '';
+            $count = 16;
+            $i = 0;
+            do {
+                $value = ord($hash[$i++]);
+                $output .= $itoa64[$value & 0x3f];
+                if ($i < $count)
+                    $value |= ord($hash[$i]) << 8;
+                $output .= $itoa64[($value >> 6) & 0x3f];
+                if ($i++ >= $count)
+                    break;
+                if ($i < $count)
+                    $value |= ord($hash[$i]) << 16;
+                $output .= $itoa64[($value >> 12) & 0x3f];
+                if ($i++ >= $count)
+                    break;
+                $output .= $itoa64[($value >> 18) & 0x3f];
+            } while ($i < $count);
+
+            return '$'.$key.'$'.$iterc.$salt.$output;
         default:
             msg("Unsupported crypt method $method",-1);
     }
@@ -1043,6 +1084,12 @@ function auth_verifyPassword($clear,$crypt){
     }elseif(preg_match('/^\$apr1\$([^\$]{0,8})\$/',$crypt,$m)){
         $method = 'apr1';
         $salt   = $m[1];
+    }elseif(preg_match('/^\$P\$(.{31})$/',$crypt,$m)){
+        $method = 'pmd5';
+        $salt   = $m[1];
+    }elseif(preg_match('/^\$H\$(.{31})$/',$crypt,$m)){
+        $method = 'hmd5';
+        $salt   = $m[1];
     }elseif(substr($crypt,0,6) == '{SSHA}'){
         $method = 'ssha';
         $salt   = substr(base64_decode(substr($crypt, 6)),20);