File Coverage

blib/lib/Crypt/CFB.pm
Criterion Covered Total %
statement 64 90 71.1
branch 11 32 34.3
condition 1 5 20.0
subroutine 12 15 80.0
pod 4 5 80.0
total 92 147 62.5


line stmt bran cond sub pod time code
1             package Crypt::CFB;
2 1     1   714 use vars qw($VERSION) ;
  1         2  
  1         68  
3 1     1   1029 use UNIVERSAL qw(can);
  1         14  
  1         8  
4             require Exporter;
5              
6             @ISA = qw(Exporter);
7              
8             @EXPORT = qw();
9              
10             $VERSION = 0.02;
11              
12             #
13             # The object returned by Crypt::CFB->new(,,[iv]) contains:
14             #
15             # $self->{key}: the key
16             # $self->{algo}: instantiated object of the class
17             # $self->{register}: the internal state of the Cipher Feedback mode
18             # $self->{registerlength}: the length of the internal state in bytes
19             # $self->{bytes}: the number of bytes to xor per round
20             # $self->{iv}: a block of $self->{bytes} bytes, containing the
21             # Initialization Vector.
22             # $self->{cf}: anonymous subroutine without parameters. The
23             # subs in this implementation read $self->{key}
24             # and $self->{register}, apply the cryptographic
25             # one-way function and return its output. This is
26             # the stuff that is XORed to the cleartext in
27             # Crypt::CFB::encrypt.
28             # $self->{statef}: reference to a sub which updates the internal
29             # state after each $self->{cf} call.
30             # $self->{epattern}, $self->{rpattern}, $self->{spattern}:
31             # diverse patterns for pack/unpack, which are
32             # computed at instantiation.
33             #
34             # If you want to create another PurePerl Cipher Mode which is
35             # basically a stream cipher, then you can simply overload
36             # $self->{statef} and $self->{cf}. See for example Crypt::Ctr.
37             #
38              
39             sub _statef;
40             sub _reginit;
41              
42             sub new {
43 1     1 1 1298262 my ($proto, $key, $algo, $iv) = @_;
44 1   33     27 my $class = ref($proto) || $proto;
45 1         7 my $self = {};
46              
47             # The number of bytes that are extracted per round
48             # from the cipher/digest's output
49              
50 1         11 $self->{bytes} = 1; # XXX unused
51 1         6 $self->{key} = $key;
52 1     0   16 $self->{cf} = sub {die "Don't forget to set the key stream function";};
  0         0  
53              
54 1         151 eval "require $algo;";
55 1 50       11 if ($@) {
56 0         0 die "Could not instantiate $algo: $!";
57             }
58              
59             # We allow cryptographic one-way functions,
60             # i.e. ciphers and hashes.
61              
62 1 50       17 if ($algo =~ m/^Crypt::/) {
    50          
63 0         0 _Crypt_new($self, $algo, $key);
64             } elsif ( $algo =~ m/^Digest::/) {
65 1         8 _Digest_new($self, $algo, $key);
66             } else {
67 0         0 die "Algorithm should belong to Crypt:: or Digest::";
68             }
69              
70             # These are patterns for pack/unpack which are
71             # subsequently used a lot.
72              
73 1         11 $self->{epattern} = "x" . ($self->{registerlength} - $self->{bytes}) .
74             "a" . $self->{bytes};
75 1         6 $self->{rpattern} = "x" . $self->{bytes} .
76             "a" . ($self->{registerlength} - $self->{bytes});
77 1         5 $self->{spattern} = "a" . $self->{bytes} . "a*";
78              
79             # Store the Initialization Vector
80 1 50       4 if (defined($iv)) {
81 0         0 $self->{iv} = $iv;
82             }
83              
84             # Initialize the internal state.
85 1         4 $self->{register} = _reginit($self);
86              
87             # This is the function that does per-round manipulation
88             # of the internal state.
89 1         6 $self->{statef} = \&_statef;
90              
91 1         3 bless ($self, $class);
92 1         4 return $self;
93             }
94              
95             sub _Digest_new {
96 1     1   9 my ($self, $algo, $key) = @_;
97 1         18 $self->{algo} = $algo->new();
98 1 50       8 if ($@) {
99 0         0 die "Could not instantiate $algo: $!";
100             }
101              
102             # The Digest class has no "blocklength" method,
103             # but that's no problem
104 1         11 $self->{algo}->add("");
105 1         9 $self->{registerlength} = length ($self->{algo}->digest);
106 1 50       5 if (not $self->{registerlength}) {
107 0         0 die "Could not set registerlength";
108             }
109              
110             # Anonymous function to produce the keystream
111             $self->{cf} = sub {
112 442     442   2533 $self->{algo}->add($self->{key} . $self->{register});
113 442         3912 return $self->{algo}->digest;
114             }
115 1         12 }
116              
117             sub _Crypt_new {
118 0     0   0 my ($self, $algo, $key) = @_;
119 0         0 eval "require $algo;";
120              
121 0 0       0 if ($@) {
122 0         0 die "Could not instantiate $algo: $!";
123             }
124              
125             # Crypt::Blowfish returns keysize 0, so we take
126             # the maximum in that case
127              
128 0 0 0     0 if (length $key > ( $algo->keysize || 56)) {
129 0         0 $key = substr $key, 0, $algo->keysize;
130             }
131              
132             # We could check for correct keysizes, but the
133             # Crypt:: algorithms throw an error anyway.
134              
135 0         0 $self->{algo} = $algo->new($key);
136              
137 0 0       0 if ($@) {
138 0         0 die "Could not instantiate $algo: $!";
139             }
140              
141 0 0       0 if (not $self->{algo}->can('blocksize')) {
142 0         0 die "$algo does not implement blocksize";
143             }
144              
145 0         0 $self->{registerlength} = $self->{algo}->blocksize;
146              
147 0 0       0 if (not $self->{registerlength}) {
148 0         0 die "Could not set registerlength";
149             }
150              
151             # Anonymous function to produce the keystream
152             $self->{cf} = sub {
153 0     0   0 return $self->{algo}->encrypt($self->{register});
154             }
155 0         0 }
156              
157             sub _reginit {
158 3     3   10 my $self = shift;
159 3 50       30 my $iv = defined($self->{iv}) ? $self->{iv} : "";
160 3         11 my $remainder = $self->{registerlength} - length($iv);
161 3         18 return $iv . ("\x0" x $remainder);
162             }
163              
164             # Per $self->{bytes} encryption/decryption
165             sub bencrypt {
166 442     442 0 986 my ($self, $block, $d) = @_;
167 442         636 my $xor = &{$self->{cf}}();
  442         2919  
168 442         5799 $xor = substr $xor, -($self->{bytes}), $self->{bytes};
169             # $xor = unpack $self->{epattern}, $xor;
170 442 50       1689 if ($self->{bytes} > 1) {
171 0 0       0 if (length $block < length $xor) {
172 0         0 $xor = substr $xor, 0, (length $block);
173             }
174             }
175 442         1264 my $out = $block ^ $xor;
176 442 100       689 if ($d) {
177 221         213 &{$self->{statef}}($self,$block);
  221         487  
178             } else {
179 221         219 &{$self->{statef}}($self,$out);
  221         756  
180             }
181 442         3912 return $out;
182             }
183              
184             sub _encrypt {
185 2     2   5 my ($self, $string, $d) = @_;
186 2         3 my ($out, $i, $l);
187 2         3 $l = length ($string);
188 2         6 for ($i = 0; $i < $l; $i += $self->{bytes}) {
189 442         2941 $out .= bencrypt ($self, (substr $string, $i, $self->{bytes}) , $d);
190             }
191 2         12 return $out;
192             }
193              
194             sub encrypt {
195 1     1 1 6 my ($self, $string) = @_;
196 1         5 return _encrypt($self, $string, 0);
197             }
198              
199             sub decrypt {
200 1     1 1 84 my ($self, $string) = @_;
201 1         4 return _encrypt($self, $string, 1);
202             }
203            
204             # Reset the internal state
205             sub reset {
206 2     2 1 17 my ($self, $iv) = @_;
207 2 50       8 if (defined($iv)) {
208 0         0 $self->{iv} = $iv;
209             }
210 2         5 $self->{register} = _reginit($self);
211             }
212              
213             # This manipulates the internal state
214             sub _statef {
215 442     442   1410 my ($self, $c) = @_;
216 442         2696 $self->{register} = (unpack $self->{rpattern}, $self->{register}) . $c;
217             }
218              
219             1;
220              
221             __END__