X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-perl/blobdiff_plain/f9952aec1cf6c64a5681308eea817b6113a37433..fcd15e0b7a3d0f0ca2f30953573f8d1f6b8e8bd2:/Catacomb/Crypto.pm diff --git a/Catacomb/Crypto.pm b/Catacomb/Crypto.pm new file mode 100644 index 0000000..c4e886d --- /dev/null +++ b/Catacomb/Crypto.pm @@ -0,0 +1,213 @@ +# -*-perl-*- +# +# $Id$ +# +# Cryptographic algorithms +# +# (c) 2004 Straylight/Edgeware +# + +#----- Licensing notice ----------------------------------------------------- +# +# This file is part of the Perl interface to Catacomb. +# +# Catacomb/Perl is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# Catacomb/Perl is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Catacomb/Perl; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#----- Symmetric crypto algorithms ----------------------------------------- + +package Catacomb; +use Catacomb::Base; +use Exporter; + +foreach my $i (qw(PRP Cipher Hash MAC)) { + my $tag = lc($i); + my @v = (); + my $cl = "Catacomb::${i}Class"; + foreach my $c (Catacomb::list($tag)) { + (my $x = $c) =~ tr/a-zA-Z0-9/_/cs; + $$x = undef; # SUYB + $$x = $cl->find($c); + push(@v, "\$$x"); + } + $EXPORT_TAGS{$tag} = \@v; + Exporter::export_ok_tags($tag); +} + +package Catacomb::PRPClass; +use Carp; + +sub eblk { + croak("Usage: Catacomb::PRPClass::eblk(pc, k, pt)") unless @_ == 3; + my ($pc, $k, $pt) = @_; + my $P = $pc->init($k); + return $P->eblk($pt); +} + +sub dblk { + croak("Usage: Catacomb::PRPClass::dblk(pc, k, ct)") unless @_ == 3; + my ($pc, $k, $pt) = @_; + my $P = $pc->init($k); + return $P->dblk($ct); +} + +package Catacomb::CipherClass; +use Carp; + +sub encrypt { + croak("Usage: Catacomb::CipherClass::encrypt(cc, k, [iv], plain)") + if @_ < 3 || @_ > 4; + my ($cc, $k, $iv, $p) = @_; + if (@_ == 3) { + $p = $iv; + $iv = undef; + } + my $c = $cc->init($k); + $c->setiv($iv) if defined($iv); + return $c->encrypt($p); +} + +sub decrypt { + croak("Usage: Catacomb::CipherClass::decrypt(cc, k, [iv], cipher)") + if @_ < 3 || @_ > 4; + my ($cc, $k, $iv, $p) = @_; + if (@_ == 3) { + $p = $iv; + $iv = undef; + } + my $c = $cc->init($k); + $c->setiv($iv) if defined($iv); + return $c->decrypt($p); +} + +package Catacomb::HashClass; +use Carp; + +sub hash { + croak("Usage: Catacomb::HashClass::hash(hc, p)") unless @_ == 2; + my ($hc, $p) = @_; + my $h = $hc->init(); + $h->hash($p); + return $h->done(); +} + +package Catacomb::MACClass; +use Carp; + +sub mac { + croak("Usage: Catacomb::MACClass::mac(mc, k, p)") unless @_ == 3; + my ($mc, $k, $p) = @_; + my $m = $mc->key($k); + return $m->hash($p); +} + +package Catacomb::MAC; +use Carp; + +sub hash { + croak("Usage: Catacomb::MAC::hash(m, p)") unless @_ == 2; + my ($m, $p) = @_; + my $h = $m->init(); + $h->hash($p); + return $h->done(); +} + +#----- DSA and KCDSA signing ------------------------------------------------ + +package Catacomb::DSA; +use Carp; +sub new { + croak("Usage: ${me}::new(me, info)") unless @_ == 2; + my ($me, $info) = @_; + return bless $info, $me; +} + +*Catacomb::KCDSA::new = \&new; + +foreach my $i (qw(DSA KCDSA)) { + @{"Catacomb::${i}::Public::ISA"} = ("Catacomb::${i}"); + @{"Catacomb::${i}::Private::ISA"} = ("Catacomb::${i}::Public"); +} + +#----- RSA signing and encryption ------------------------------------------- + +package Catacomb::RSA::Pad; +use Carp; + +sub new { + croak("Usage: ${me}::new(me, info)") unless @_ == 2; + my ($me, $info) = @_; + return bless $info, $me; +} + +foreach my $i (qw(PKCS1Crypt PKCS1Sign OAEP PSS)) { + @{"Catacomb::RSA::${i}::ISA"} = qw(Catacomb::RSA::Pad); +} + +package Catacomb::RSA::Public; +use Carp; +use Catacomb::Base; +use Catacomb::MP; + +sub encrypt { + croak("Usage: Catacomb::RSA::Public::encrypt(pub, pad, msg)") + unless @_ == 3; + my ($pub, $pad, $msg) = @_; + my $n = $pub->n(); + my $r = $pad->pad($msg, $n->octets(), $n->bits()); + return undef unless defined($r); + return $pub->op($r); +} + +sub verify { + croak("Usage: Catacomb::RSA::Public::verify(pub, pad, sig, [msg])") + unless @_ >= 3 && @_ <= 4; + my ($pub, $pad, $sig, $msg) = @_; + my $n = $pub->n(); + my $rc = $pad->unpad($pub->op($sig), $msg, $n->octets(), $n->bits()); + return undef unless defined($rc); + if (defined($msg)) { + return undef unless $rc eq "" || $rc eq $msg; + return 1; + } else { + return $rc; + } +} + +package Catacomb::RSA::Private; +use Carp; +use Catacomb::Base; +use Catacomb::MP; + +sub sign { + croak("Usage: Catacomb::RSA::Private::sign(priv, pad, msg, [rng]") + unless @_ >= 3 && @_ <= 4; + my ($priv, $pad, $msg, $rng) = @_; + my $n = $priv->n(); + my $r = $pad->pad($msg, $n->octets(), $n->bits()); + return undef unless defined($r); + return $priv->op($r, $rng); +} + +sub decrypt { + croak("Usage: Catacomb::RSA::Private::decrypt(priv, pad, ct, [rng]") + unless @_ >= 3 && @_ <= 4; + my ($priv, $pad, $ct, $rng) = @_; + my $n = $priv->n(); + return $pad->unpad($priv->op($ct, $rng), $n->octets(), $n->bits()); +} + +#----- That's all, folks ---------------------------------------------------- + +1;