# 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 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; I 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