← Index
NYTProf Performance Profile   « line view »
For t/bug-md-11.t
  Run on Fri Mar 8 13:27:24 2024
Reported on Fri Mar 8 13:30:23 2024

Filename/home/micha/Projekt/spreadsheet-parsexlsx/lib/Spreadsheet/ParseXLSX/Decryptor/Agile.pm
StatementsExecuted 7 statements in 371µs
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
11111µs12µsSpreadsheet::ParseXLSX::Decryptor::Agile::::BEGIN@3Spreadsheet::ParseXLSX::Decryptor::Agile::BEGIN@3
1113µs48µsSpreadsheet::ParseXLSX::Decryptor::Agile::::BEGIN@10Spreadsheet::ParseXLSX::Decryptor::Agile::BEGIN@10
1113µs19µsSpreadsheet::ParseXLSX::Decryptor::Agile::::BEGIN@4Spreadsheet::ParseXLSX::Decryptor::Agile::BEGIN@4
0000s0sSpreadsheet::ParseXLSX::Decryptor::Agile::::_generateDecryptionKeySpreadsheet::ParseXLSX::Decryptor::Agile::_generateDecryptionKey
0000s0sSpreadsheet::ParseXLSX::Decryptor::Agile::::_generateInitializationVectorSpreadsheet::ParseXLSX::Decryptor::Agile::_generateInitializationVector
0000s0sSpreadsheet::ParseXLSX::Decryptor::Agile::::decryptSpreadsheet::ParseXLSX::Decryptor::Agile::decrypt
0000s0sSpreadsheet::ParseXLSX::Decryptor::Agile::::decryptFileSpreadsheet::ParseXLSX::Decryptor::Agile::decryptFile
0000s0sSpreadsheet::ParseXLSX::Decryptor::Agile::::verifyPasswordSpreadsheet::ParseXLSX::Decryptor::Agile::verifyPassword
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1package Spreadsheet::ParseXLSX::Decryptor::Agile;
2
3217µs214µs
# spent 12µs (11+2) within Spreadsheet::ParseXLSX::Decryptor::Agile::BEGIN@3 which was called: # once (11µs+2µs) by Spreadsheet::ParseXLSX::Decryptor::BEGIN@19 at line 3
use strict;
# spent 12µs making 1 call to Spreadsheet::ParseXLSX::Decryptor::Agile::BEGIN@3 # spent 2µs making 1 call to strict::import
4221µs235µs
# spent 19µs (3+16) within Spreadsheet::ParseXLSX::Decryptor::Agile::BEGIN@4 which was called: # once (3µs+16µs) by Spreadsheet::ParseXLSX::Decryptor::BEGIN@19 at line 4
use warnings;
# spent 19µs making 1 call to Spreadsheet::ParseXLSX::Decryptor::Agile::BEGIN@4 # spent 16µs making 1 call to warnings::import
5
6# VERSION
7
8# ABSTRACT: decryptor for files of version 4.4
9
102331µs293µs
# spent 48µs (3+45) within Spreadsheet::ParseXLSX::Decryptor::Agile::BEGIN@10 which was called: # once (3µs+45µs) by Spreadsheet::ParseXLSX::Decryptor::BEGIN@19 at line 10
use base 'Spreadsheet::ParseXLSX::Decryptor';
# spent 48µs making 1 call to Spreadsheet::ParseXLSX::Decryptor::Agile::BEGIN@10 # spent 45µs making 1 call to base::import
11
12sub decrypt {
13 my $self = shift;
14 my ($encryptedValue, $blockKey) = @_;
15
16 my $key = $self->_generateDecryptionKey($blockKey);
17 my $iv = $self->_generateInitializationVector('', $self->{blockSize});
18 my $cbc = Crypt::Mode::CBC->new($self->{cipherAlgorithm}, 0);
19 return $cbc->decrypt($encryptedValue, $key, $iv);
20}
21
22sub _generateDecryptionKey {
23 my $self = shift;
24 my ($blockKey) = @_;
25
26 my $hash;
27
28 unless ($self->{pregeneratedKey}) {
29 $hash = $self->{hashProc}->($self->{salt} . Encode::encode('UTF-16LE', $self->{password}));
30 for (my $i = 0 ; $i < $self->{spinCount} ; $i++) {
31 $hash = $self->{hashProc}->(pack('L<', $i) . $hash);
32 }
33 $self->{pregeneratedKey} = $hash;
34 }
35
36 $hash = $self->{hashProc}->($self->{pregeneratedKey} . $blockKey);
37
38 if (length($hash) > $self->{keyLength}) {
39 $hash = substr($hash, 0, $self->{keyLength});
40 } elsif (length($hash) < $self->{keyLength}) {
41 $hash .= "\x36" x ($self->{keyLength} - length($hash));
42 }
43 return $hash;
44}
45
46sub _generateInitializationVector {
47 my $self = shift;
48 my ($blockKey, $blockSize) = @_;
49
50 my $iv;
51 if ($blockKey) {
52 $iv = $self->{hashProc}->($self->{salt} . $blockKey);
53 } else {
54 $iv = $self->{salt};
55 }
56
57 if (length($iv) > $blockSize) {
58 $iv = substr($iv, 0, $blockSize);
59 } elsif (length($iv) < $blockSize) {
60 $iv = $iv . ("\x36" x ($blockSize - length($iv)));
61 }
62
63 return $iv;
64}
65
66sub decryptFile {
67 my $self = shift;
68 my ($inFile, $outFile, $bufferLength, $key, $fileSize) = @_;
69
70 my $cbc = Crypt::Mode::CBC->new($self->{cipherAlgorithm}, 0);
71
72 my $inbuf;
73 my $i = 0;
74
75 while (($fileSize > 0) && (my $inlen = $inFile->read($inbuf, $bufferLength))) {
76 my $blockId = pack('L<', $i);
77
78 my $iv = $self->_generateInitializationVector($blockId, $self->{blockSize});
79
80 if ($inlen < $bufferLength) {
81 $inbuf .= "\x00" x ($bufferLength - $inlen);
82 }
83
84 my $outbuf = $cbc->decrypt($inbuf, $key, $iv);
85 if ($fileSize < $inlen) {
86 $inlen = $fileSize;
87 }
88
89 $outFile->write($outbuf, $inlen);
90 $i++;
91 $fileSize -= $inlen;
92 }
93}
94
95sub verifyPassword {
96 my $self = shift;
97 my ($encryptedVerifier, $encryptedVerifierHash, $hashSize) = @_;
98
99 my $encryptedVerifierHash0 = $self->{hashProc}->($self->decrypt($encryptedVerifier, "\xfe\xa7\xd2\x76\x3b\x4b\x9e\x79"));
100 $encryptedVerifierHash = $self->decrypt($encryptedVerifierHash, "\xd7\xaa\x0f\x6d\x30\x61\x34\x4e");
101 $encryptedVerifierHash0 = substr($encryptedVerifierHash0, 0, $hashSize);
102 $encryptedVerifierHash = substr($encryptedVerifierHash, 0, $hashSize);
103
104 die "Wrong password: $self" unless ($encryptedVerifierHash0 eq $encryptedVerifierHash);
105}
106
107=begin Pod::Coverage
108
109 decrypt
110 decryptFile
111 verifyPassword
112
113=end Pod::Coverage
114
115=cut
116
11712µs1;