File Coverage

blib/lib/Crypt/OpenPGP/Cipher.pm
Criterion Covered Total %
statement 130 162 80.2
branch 11 18 61.1
condition 1 3 33.3
subroutine 52 66 78.7
pod 5 8 62.5
total 199 257 77.4


line stmt bran cond sub pod time code
1             package Crypt::OpenPGP::Cipher;
2 1     1   677 use strict;
  1         2  
  1         38  
3              
4 1     1   588 use Crypt::OpenPGP::CFB;
  1         2  
  1         30  
5 1     1   538 use Crypt::OpenPGP::ErrorHandler;
  1         3  
  1         31  
6 1     1   6 use base qw( Crypt::OpenPGP::ErrorHandler );
  1         2  
  1         134  
7              
8 1     1   5 use vars qw( %ALG %ALG_BY_NAME );
  1         3  
  1         718  
9             %ALG = (
10             1 => 'IDEA',
11             2 => 'DES3',
12             3 => 'CAST5',
13             4 => 'Blowfish',
14             7 => 'Rijndael',
15             8 => 'Rijndael192',
16             9 => 'Rijndael256',
17             10 => 'Twofish',
18             );
19             %ALG_BY_NAME = map { $ALG{$_} => $_ } keys %ALG;
20              
21             sub new {
22 12     12 1 273 my $class = shift;
23 12         18 my $alg = shift;
24 12   33     41 $alg = $ALG{$alg} || $alg;
25 12 50       38 return $class->error("Unsupported cipher algorithm '$alg'")
26             unless $alg =~ /^\D/;
27 12         33 my $pkg = join '::', $class, $alg;
28 12         63 my $ciph = bless { __alg => $alg,
29             __alg_id => $ALG_BY_NAME{$alg} }, $pkg;
30 12         35 my $impl_class = $ciph->crypt_class;
31 12 50       38 my @classes = ref($impl_class) eq 'ARRAY' ? @$impl_class : ($impl_class);
32 12         23 for my $c (@classes) {
33 1     1   506 eval "use $c;";
  0     1   0  
  0     1   0  
  1     1   573  
  0     1   0  
  0     1   0  
  1     1   429  
  0     1   0  
  0     1   0  
  1     1   401  
  0     1   0  
  0     1   0  
  1         508  
  0         0  
  0         0  
  1         495  
  0         0  
  0         0  
  1         1016  
  1         2621  
  1         18  
  1         987  
  1         1018  
  1         34  
  1         107  
  1         2  
  1         18  
  1         7  
  1         2  
  1         13  
  1         7  
  1         3  
  1         49  
  1         6  
  1         2  
  1         31  
  12         944  
34 12 100       475 $ciph->{__impl} = $c, last unless $@;
35             }
36 12 100       107 return $class->error("Error loading cipher implementation for " .
37             "'$alg': no implementations installed.")
38             unless $ciph->{__impl};
39 6         34 $ciph->init(@_);
40             }
41              
42             sub init {
43 3     3 0 6 my $ciph = shift;
44 3         8 my($key, $iv) = @_;
45 3 100       10 if ($key) {
46 2         6 my $class = $ciph->{__impl};
47             ## Make temp variable, because Rijndael checks SvPOK, which
48             ## doesn't seem to like a value that isn't a variable?
49 2         7 my $tmp = substr $key, 0, $ciph->keysize;
50 2         10 my $c = $class->new($tmp);
51 2         156 $ciph->{cipher} = Crypt::OpenPGP::CFB->new($c, $iv);
52             }
53 3         14 $ciph;
54             }
55              
56 4     4 1 113 sub encrypt { $_[0]->{cipher}->encrypt($_[1]) }
57 4     4 1 33 sub decrypt { $_[0]->{cipher}->decrypt($_[1]) }
58              
59 0     0 0 0 sub sync { $_[0]->{cipher}->sync }
60              
61 2     2 1 36 sub alg { $_[0]->{__alg} }
62             sub alg_id {
63 2 50   2 1 16 return $_[0]->{__alg_id} if ref($_[0]);
64 0 0       0 $ALG_BY_NAME{$_[1]} || $_[1];
65             }
66             sub supported {
67 0     0 0 0 my $class = shift;
68 0         0 my %s;
69 0         0 for my $cid (keys %ALG) {
70 0         0 my $cipher = $class->new($cid);
71 0 0       0 $s{$cid} = $cipher->alg if $cipher;
72             }
73 0         0 \%s;
74             }
75              
76             package Crypt::OpenPGP::Cipher::IDEA;
77 1     1   6 use strict;
  1         6  
  1         46  
78 1     1   6 use base qw( Crypt::OpenPGP::Cipher );
  1         2  
  1         253  
79              
80             sub init {
81 3     3   5 my $ciph = shift;
82 3         7 my($key, $iv) = @_;
83 3 100       9 if ($key) {
84 2         8 my $c = IDEA->new(substr($key, 0, $ciph->keysize));
85 2         40 $ciph->{cipher} = Crypt::OpenPGP::CFB->new($c, $iv);
86             }
87 3         13 $ciph;
88             }
89              
90 3     3   9 sub crypt_class { 'Crypt::IDEA' }
91 2     2   16 sub keysize { 16 }
92 1     1   7 sub blocksize { 8 }
93              
94             package Crypt::OpenPGP::Cipher::Blowfish;
95 1     1   6 use strict;
  1         2  
  1         39  
96 1     1   6 use base qw( Crypt::OpenPGP::Cipher );
  1         1  
  1         127  
97              
98 1     1   3 sub crypt_class { 'Crypt::Blowfish' }
99 0     0   0 sub keysize { 16 }
100 0     0   0 sub blocksize { 8 }
101              
102             package Crypt::OpenPGP::Cipher::DES3;
103 1     1   6 use strict;
  1         1  
  1         46  
104 1     1   5 use base qw( Crypt::OpenPGP::Cipher );
  1         2  
  1         123  
105              
106 3     3   6 sub crypt_class { 'Crypt::DES_EDE3' }
107 2     2   6 sub keysize { 24 }
108 1     1   7 sub blocksize { 8 }
109              
110             package Crypt::OpenPGP::Cipher::CAST5;
111 1     1   5 use strict;
  1         2  
  1         37  
112 1     1   6 use base qw( Crypt::OpenPGP::Cipher );
  1         2  
  1         127  
113              
114 1     1   2 sub crypt_class { 'Crypt::CAST5_PP' }
115 0     0   0 sub keysize { 16 }
116 0     0   0 sub blocksize { 8 }
117              
118             package Crypt::OpenPGP::Cipher::Twofish;
119 1     1   5 use strict;
  1         2  
  1         36  
120 1     1   5 use base qw( Crypt::OpenPGP::Cipher );
  1         2  
  1         141  
121              
122 1     1   2 sub crypt_class { 'Crypt::Twofish' }
123 0     0   0 sub keysize { 32 }
124 0     0   0 sub blocksize { 16 }
125              
126             package Crypt::OpenPGP::Cipher::Rijndael;
127 1     1   6 use strict;
  1         3  
  1         31  
128 1     1   5 use base qw( Crypt::OpenPGP::Cipher );
  1         2  
  1         141  
129              
130 1     1   2 sub crypt_class { 'Crypt::Rijndael' }
131 0     0   0 sub keysize { 16 }
132 0     0   0 sub blocksize { 16 }
133              
134             package Crypt::OpenPGP::Cipher::Rijndael192;
135 1     1   6 use strict;
  1         1  
  1         30  
136 1     1   13 use base qw( Crypt::OpenPGP::Cipher );
  1         1  
  1         164  
137              
138 1     1   3 sub crypt_class { 'Crypt::Rijndael' }
139 0     0   0 sub keysize { 24 }
140 0     0   0 sub blocksize { 16 }
141              
142             package Crypt::OpenPGP::Cipher::Rijndael256;
143 1     1   6 use strict;
  1         2  
  1         38  
144 1     1   4 use base qw( Crypt::OpenPGP::Cipher );
  1         3  
  1         121  
145              
146 1     1   2 sub crypt_class { 'Crypt::Rijndael' }
147 0     0     sub keysize { 32 }
148 0     0     sub blocksize { 16 }
149              
150             1;
151             __END__