diff --git a/docs/changes.txt b/docs/changes.txt index 09b617705..9dbe1a5f1 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -95,6 +95,7 @@ - User Options: added --metal-compiler-runtime option - Hardware Monitor: avoid sprintf in src/ext_iokit.c - Help: show supported hash-modes only with -hh +- Unit tests: add test modules for hash-modes 31500 and 31600 and handle them in tools/test.pl * changes v6.2.5 -> v6.2.6 diff --git a/tools/test_modules/m31500.pm b/tools/test_modules/m31500.pm new file mode 100644 index 000000000..aad5eb32a --- /dev/null +++ b/tools/test_modules/m31500.pm @@ -0,0 +1,61 @@ +#!/usr/bin/env perl + +## +## Author......: See docs/credits.txt +## License.....: MIT +## + +use strict; +use warnings; + +use Digest::MD4 qw (md4_hex); +use Text::Iconv; +use Encode; + +sub module_constraints { [[32, 32], [0, 256], [-1, -1], [-1, -1], [-1, -1]] } + +sub module_get_random_password +{ + my $word = shift; + + my $converter = Text::Iconv->new('utf8', 'UTF-16LE'); + + $word = md4_hex ($converter->convert ($word)); + + return $word; +} + +sub module_generate_hash +{ + my $word = shift; + my $salt = shift; + + my $word_bin = pack ("H*", $word); + + my $salt_bin = encode ("UTF-16LE", lc ($salt)); + + my $digest = md4_hex ($word_bin . $salt_bin); + + my $hash = sprintf ("%s:%s", $digest, $salt); + + return $hash; +} + +sub module_verify_hash +{ + my $line = shift; + + my ($hash, $salt, $word) = split (':', $line); + + return unless defined $hash; + return unless defined $salt; + return unless defined $word; + + my $word_packed = pack_if_HEX_notation ($word); + + my $new_hash = module_generate_hash ($word_packed, $salt); + + return ($new_hash, $word); +} + +1; diff --git a/tools/test_modules/m31600.pm b/tools/test_modules/m31600.pm new file mode 100644 index 000000000..ed425996e --- /dev/null +++ b/tools/test_modules/m31600.pm @@ -0,0 +1,88 @@ +#!/usr/bin/env perl + +## +## Author......: See docs/credits.txt +## License.....: MIT +## + +use strict; +use warnings; + +use Digest::MD4 qw (md4 md4_hex); +use Crypt::PBKDF2; +use Text::Iconv; +use Encode; + +sub module_constraints { [[32, 32], [0, 256], [-1, -1], [-1, -1], [-1, -1]] } + +sub module_get_random_password +{ + my $word = shift; + + my $converter = Text::Iconv->new('utf8', 'UTF-16LE'); + + $word = md4_hex ($converter->convert ($word)); + + return $word; +} + +sub module_generate_hash +{ + my $word = shift; + my $salt = shift; + my $iterations = shift // 10240; + + my $salt_bin = encode ("UTF-16LE", lc ($salt)); + + my $pbkdf2 = Crypt::PBKDF2->new + ( + hash_class => 'HMACSHA1', + iterations => $iterations, + output_len => 16, + salt_len => length ($salt_bin), + ); + + my $word_bin = pack ("H*", $word); + + my $digest = unpack ("H*", $pbkdf2->PBKDF2 ($salt_bin, md4 ($word_bin . $salt_bin))); + + my $hash = sprintf ("\$DCC2\$%i#%s#%s", $iterations, $salt, $digest); + + return $hash; +} + +sub module_verify_hash +{ + my $line = shift; + + my ($hash, $word) = split (':', $line); + + return unless defined $hash; + return unless defined $word; + + my $signature = substr ($hash, 0, 6); + + return unless ($signature eq '$DCC2$'); + + $hash = substr ($hash, 6); + + my @data = split ('#', $hash); + + return unless scalar @data == 3; + + my $iterations = shift @data; + my $salt = shift @data; + my $digest = shift @data; + + return unless defined $iterations; + return unless defined $salt; + return unless defined $digest; + + my $word_packed = pack_if_HEX_notation ($word); + + my $new_hash = module_generate_hash ($word_packed, $salt, $iterations); + + return ($new_hash, $word); +} + +1;