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 to64 16{ 17 my $v = shift; 18 my $n = shift; 19 20 my $itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 21 22 my $ret = ""; 23 24 while (($n - 1) >= 0) 25 { 26 $n = $n - 1; 27 28 $ret .= substr ($itoa64, $v & 0x3f, 1); 29 30 $v = $v >> 6; 31 } 32 33 return $ret 34} 35 36sub aix_ssha1_pbkdf2 37{ 38 my $word_buf = shift; 39 my $salt_buf = shift; 40 my $iterations = shift; 41 42 my $hasher = Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA1'); 43 44 my $pbkdf2 = Crypt::PBKDF2->new ( 45 hasher => $hasher, 46 iterations => $iterations, 47 ); 48 49 my $hash_buf = $pbkdf2->PBKDF2 ($salt_buf, $word_buf); 50 51 my $tmp_hash = ""; 52 53 $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); 54 $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); 55 $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); 56 $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); 57 $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); 58 $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); 59 $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 18, 1))) << 16) | (int (ord (substr ($hash_buf, 19, 1))) << 8) , 3); 60 61 return $tmp_hash; 62} 63 64sub module_generate_hash 65{ 66 my $word = shift; 67 my $salt = shift; 68 my $iter = shift // 64; 69 70 my $hash_buf = aix_ssha1_pbkdf2 ($word, $salt, $iter); 71 72 my $hash = sprintf ("{ssha1}%02i\$%s\$%s", log ($iter) / log (2), $salt, $hash_buf); 73 74 return $hash; 75} 76 77sub module_verify_hash 78{ 79 my $line = shift; 80 81 my $index1 = index ($line, ":"); 82 my $hash_in = substr ($line, 0, $index1); 83 84 return if $index1 < 1; 85 86 my $word = substr ($line, $index1 + 1); 87 88 my $index2 = index ($hash_in, "}"); 89 my $index3 = index ($hash_in, "\$"); 90 my $index4 = rindex ($hash_in, "\$"); 91 92 my $salt = substr ($hash_in, $index3 + 1, $index4 - $index3 - 1); 93 94 my $iter = substr ($hash_in, $index2 + 1, $index3 - $index2 - 1); 95 96 return unless defined $salt; 97 return unless defined $word; 98 return unless defined $iter; 99 100 $word = pack_if_HEX_notation ($word); 101 102 my $new_hash = module_generate_hash ($word, $salt, 1 << int ($iter)); 103 104 return ($new_hash, $word); 105} 106 1071; 108