111 lines
2.7 KiB
Perl
111 lines
2.7 KiB
Perl
# This code based slightly on the Systemics Crypt::CFB.
|
|
# Parts Copyright (C) 1995, 1996 Systemics Ltd (http://www.systemics.com/)
|
|
# All rights reserved.
|
|
|
|
package Crypt::OpenPGP::CFB;
|
|
use strict;
|
|
|
|
sub new {
|
|
my $class = shift;
|
|
my $c = bless { }, $class;
|
|
$c->init(@_);
|
|
}
|
|
|
|
sub init {
|
|
my $c = shift;
|
|
my($cipher, $iv) = @_;
|
|
$c->{cipher} = $cipher;
|
|
$c->{blocksize} = $cipher->blocksize;
|
|
$c->{iv} = $iv || "\0" x $c->{blocksize};
|
|
$c;
|
|
}
|
|
|
|
sub sync { $_[0]->{unused} = '' }
|
|
|
|
sub encrypt {
|
|
my $c = shift;
|
|
my($data) = @_;
|
|
my $ret = '';
|
|
my $iv = $c->{iv};
|
|
my $out = $c->{unused} || '';
|
|
my $size = length $out;
|
|
while ( $data ne '' ) {
|
|
unless ($size) {
|
|
$out = $c->{cipher}->encrypt($iv);
|
|
$size = $c->{blocksize};
|
|
}
|
|
my $in = substr $data, 0, $size, '';
|
|
$size -= (my $got = length $in);
|
|
$iv .= ($in ^= substr $out, 0, $got, '');
|
|
substr $iv, 0, $got, '';
|
|
$ret .= $in;
|
|
}
|
|
$c->{unused} = $out;
|
|
$c->{iv} = $iv;
|
|
$ret;
|
|
}
|
|
|
|
sub decrypt {
|
|
my $c = shift;
|
|
my($data) = @_;
|
|
my $ret = '';
|
|
my $iv = $c->{iv};
|
|
my $out = $c->{unused} || '';
|
|
my $size = length $out;
|
|
while ( $data ne '' ) {
|
|
unless ($size) {
|
|
$out = $c->{cipher}->encrypt($iv);
|
|
$size = $c->{blocksize};
|
|
}
|
|
my $in = substr $data, 0, $size, '';
|
|
$size -= (my $got = length $in);
|
|
substr $iv .= $in, 0, $got, '';
|
|
$ret .= ($in ^= substr $out, 0, $got, '');
|
|
}
|
|
$c->{unused} = $out;
|
|
$c->{iv} = $iv;
|
|
$ret;
|
|
}
|
|
|
|
1;
|
|
__END__
|
|
|
|
=head1 NAME
|
|
|
|
Crypt::OpenPGP::CFB - PGP Cipher Feedback Mode
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
use Crypt::OpenPGP::CFB;
|
|
|
|
my $key = 'foo bar';
|
|
my $cipher = Crypt::Blowfish->new( $key ); # for example
|
|
my $cfb = Crypt::OpenPGP::CFB->new( $cipher );
|
|
|
|
my $plaintext = 'this is secret!';
|
|
my $ct = $cfb->encrypt( $plaintext );
|
|
|
|
my $pt = $cfb->decrypt( $ct );
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
I<Crypt::OpenPGP::CFB> implements the variant of Cipher Feedback mode
|
|
that PGP uses in its encryption and decryption. The key difference
|
|
with PGP CFB is that the CFB state is resynchronized at each
|
|
encryption/decryption. This applies both when encrypting secret key
|
|
data and in symmetric encryption of standard encrypted data. More
|
|
differences are described in the OpenPGP RFC, in section 13.9
|
|
(OpenPGP CFB mode).
|
|
|
|
Typically you should never need to directly use I<Crypt::OpenPGP::CFB>;
|
|
I<Crypt::OpenPGP::Cipher> objects wrap around an instance of this
|
|
class and provide a uniform interface to symmetric ciphers. See
|
|
the documentation for that module for usage details.
|
|
|
|
=head1 AUTHOR & COPYRIGHTS
|
|
|
|
Please see the Crypt::OpenPGP manpage for author, copyright, and
|
|
license information.
|
|
|
|
=cut
|