diff --git a/tools/test_modules/m10700.pm b/tools/test_modules/m10700.pm new file mode 100644 index 000000000..24cf712c5 --- /dev/null +++ b/tools/test_modules/m10700.pm @@ -0,0 +1,142 @@ +#!/usr/bin/env perl + +## +## Author......: See docs/credits.txt +## License.....: MIT +## + +use strict; +use warnings; + +use Crypt::CBC; +use Digest::SHA qw (sha256 sha384 sha512); + +sub module_constraints { [[1, 255], [32, 32], [1, 15], [32, 32], [-1, -1]] } + +sub module_generate_hash +{ + my $word = shift; + my $id = shift; + my $rest = shift; + + if (defined $id == 0) + { + $id = "0" x 32; + } + + if (defined $rest == 0) + { + $rest = "127*"; + $rest .= "0" x 64; + $rest .= $id; + $rest .= "0" x 158; + $rest .= "*127*00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000*32*0000000000000000000000000000000000000000000000000000000000000000*32*0000000000000000000000000000000000000000000000000000000000000000"; + } + + my @datax = split /\*/, $rest; + + my $u = pack ("H*", $datax[1]); + + my $block = sha256 ($word . substr ($u, 32, 8)); + + my $block_size = 32; + + my $data = 0x00 x 64; + + my $data_len = 1; + + my $data63 = 0; + + for (my $i = 0; $i < 64 || $i < $data63 + 32; $i++) + { + $data = $word . $block; + + $data_len = length ($data); + + for (my $k = 1; $k < 64; $k++) + { + $data .= $word . $block; + } + + my $aes = Crypt::CBC->new ({ + key => substr ($block, 0, 16), + cipher => "Crypt::Rijndael", + iv => substr ($block, 16, 16), + literal_key => 1, + header => "none", + keysize => 16, + padding => "null", + }); + + my $data = $aes->encrypt ($data); + + my $sum = 0; + + for (my $j = 0; $j < 16; $j++) + { + $sum += ord (substr ($data, $j, 1)); + } + + $block_size = 32 + ($sum % 3) * 16; + + if ($block_size == 32) + { + $block = sha256 (substr ($data, 0, $data_len * 64)); + } + elsif ($block_size == 48) + { + $block = sha384 (substr ($data, 0, $data_len * 64)); + } + elsif ($block_size == 64) + { + $block = sha512 (substr ($data, 0, $data_len * 64)); + } + + $data63 = ord (substr ($data, $data_len * 64 - 1, 1)); + } + + $datax[1] = unpack ("H*", substr ($block, 0, 32) . substr ($u, 32)); + + $rest = join ("*", @datax); + + my $hash = sprintf ('$pdf$5*6*256*-1028*1*16*%s*%s', $id, $rest); + + return $hash; +} + +sub module_verify_hash +{ + my $line = shift; + + # PDF 1.7 Level 8 (Acrobat 10 - 11) + my ($hash_in, $word) = split ":", $line; + + return unless defined $hash_in; + return unless defined $word; + + my @data = split /\*/, $hash_in; + + return unless scalar @data >= 11; + + return unless (shift @data eq '$pdf$5'); + return unless (shift @data eq '6'); + return unless (shift @data eq '256'); + return unless (shift @data eq '-1028'); + return unless (shift @data eq '1'); + return unless (shift @data eq '16'); + + my $id = shift @data; + my $rest = join "*", @data; + + return unless defined $id; + return unless defined $rest; + return unless defined $word; + + $word = pack_if_HEX_notation ($word); + + my $new_hash = module_generate_hash ($word, $id, $rest); + + return ($new_hash, $word); +} + +1;