1#!/usr/bin/env perl 2 3## 4## Author......: See docs/credits.txt 5## License.....: MIT 6## 7 8use strict; 9use warnings; 10 11use Crypt::PBKDF2; 12 13sub module_constraints { [[0, 256], [16, 16], [-1, -1], [-1, -1], [-1, -1]] } 14 15sub module_generate_hash 16{ 17 my $word = shift; 18 my $salt = shift; 19 my $iter = shift; 20 21 my $iterations = 64; 22 23 if (length ($iter)) 24 { 25 $iterations = 1 << int ($iter); 26 } 27 28 my $digest = aix_ssha512_pbkdf2 ($word, $salt, $iterations); 29 30 my $hash = sprintf ("{ssha512}%02i\$%s\$%s", log ($iterations) / log (2), $salt, $digest); 31 32 return $hash; 33} 34 35sub module_verify_hash 36{ 37 my $line = shift; 38 39 my ($hash, $word) = split (':', $line); 40 41 return unless defined $hash; 42 return unless defined $word; 43 44 my $signature = substr ($hash, 0, 9); 45 46 return unless ($signature eq "{ssha512}"); 47 48 $hash = substr ($hash, 9); 49 50 my @data = split ('\$', $hash); 51 52 return unless scalar @data == 3; 53 54 my $iter = shift (@data); 55 my $salt = shift @data; 56 my $digest = shift @data; 57 58 my $word_packed = pack_if_HEX_notation ($word); 59 60 my $new_hash = module_generate_hash ($word_packed, $salt, $iter); 61 62 return ($new_hash, $word); 63} 64 65sub aix_ssha512_pbkdf2 66{ 67 my $word_buf = shift; 68 my $salt_buf = shift; 69 my $iterations = shift; 70 71 my $hasher = Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 512); 72 73 my $pbkdf2 = Crypt::PBKDF2->new ( 74 hasher => $hasher, 75 iterations => $iterations, 76 ); 77 78 my $hash_buf = $pbkdf2->PBKDF2 ($salt_buf, $word_buf); 79 80 my $tmp_hash = ""; 81 82 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 0, 1))) << 16) | (int (ord (substr ($hash_buf, 1, 1))) << 8) | (int (ord (substr ($hash_buf, 2, 1)))), 4); 83 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 3, 1))) << 16) | (int (ord (substr ($hash_buf, 4, 1))) << 8) | (int (ord (substr ($hash_buf, 5, 1)))), 4); 84 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 6, 1))) << 16) | (int (ord (substr ($hash_buf, 7, 1))) << 8) | (int (ord (substr ($hash_buf, 8, 1)))), 4); 85 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 9, 1))) << 16) | (int (ord (substr ($hash_buf, 10, 1))) << 8) | (int (ord (substr ($hash_buf, 11, 1)))), 4); 86 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 12, 1))) << 16) | (int (ord (substr ($hash_buf, 13, 1))) << 8) | (int (ord (substr ($hash_buf, 14, 1)))), 4); 87 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 15, 1))) << 16) | (int (ord (substr ($hash_buf, 16, 1))) << 8) | (int (ord (substr ($hash_buf, 17, 1)))), 4); 88 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 18, 1))) << 16) | (int (ord (substr ($hash_buf, 19, 1))) << 8) | (int (ord (substr ($hash_buf, 20, 1)))), 4); 89 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 21, 1))) << 16) | (int (ord (substr ($hash_buf, 22, 1))) << 8) | (int (ord (substr ($hash_buf, 23, 1)))), 4); 90 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 24, 1))) << 16) | (int (ord (substr ($hash_buf, 25, 1))) << 8) | (int (ord (substr ($hash_buf, 26, 1)))), 4); 91 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 27, 1))) << 16) | (int (ord (substr ($hash_buf, 28, 1))) << 8) | (int (ord (substr ($hash_buf, 29, 1)))), 4); 92 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 30, 1))) << 16) | (int (ord (substr ($hash_buf, 31, 1))) << 8) | (int (ord (substr ($hash_buf, 32, 1)))), 4); 93 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 33, 1))) << 16) | (int (ord (substr ($hash_buf, 34, 1))) << 8) | (int (ord (substr ($hash_buf, 35, 1)))), 4); 94 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 36, 1))) << 16) | (int (ord (substr ($hash_buf, 37, 1))) << 8) | (int (ord (substr ($hash_buf, 38, 1)))), 4); 95 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 39, 1))) << 16) | (int (ord (substr ($hash_buf, 40, 1))) << 8) | (int (ord (substr ($hash_buf, 41, 1)))), 4); 96 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 42, 1))) << 16) | (int (ord (substr ($hash_buf, 43, 1))) << 8) | (int (ord (substr ($hash_buf, 44, 1)))), 4); 97 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 45, 1))) << 16) | (int (ord (substr ($hash_buf, 46, 1))) << 8) | (int (ord (substr ($hash_buf, 47, 1)))), 4); 98 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 48, 1))) << 16) | (int (ord (substr ($hash_buf, 49, 1))) << 8) | (int (ord (substr ($hash_buf, 50, 1)))), 4); 99 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 51, 1))) << 16) | (int (ord (substr ($hash_buf, 52, 1))) << 8) | (int (ord (substr ($hash_buf, 53, 1)))), 4); 100 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 54, 1))) << 16) | (int (ord (substr ($hash_buf, 55, 1))) << 8) | (int (ord (substr ($hash_buf, 56, 1)))), 4); 101 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 57, 1))) << 16) | (int (ord (substr ($hash_buf, 58, 1))) << 8) | (int (ord (substr ($hash_buf, 59, 1)))), 4); 102 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 60, 1))) << 16) | (int (ord (substr ($hash_buf, 61, 1))) << 8) | (int (ord (substr ($hash_buf, 62, 1)))), 4); 103 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 63, 1))) << 16) , 2); 104 105 return $tmp_hash; 106} 107 108sub to64 109{ 110 my $v = shift; 111 my $n = shift; 112 113 my $itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 114 115 my $ret = ""; 116 117 while (($n - 1) >= 0) 118 { 119 $n = $n - 1; 120 121 $ret .= substr ($itoa64, $v & 0x3f, 1); 122 123 $v = $v >> 6; 124 } 125 126 return $ret 127} 128 1291; 130