1# Filename: Mcrypt.pm
2# Author:   Theo Schlossnagle <jesus@omniti.com>
3# Created:  17th January 2001
4# Version:  2.5.7.0
5#
6# Copyright (c) 1999,2001,2007 Theo Schlossnagle. All rights reserved.
7#   This program is free software; you can redistribute it and/or
8#   modify it under the same terms as Perl itself.
9#
10#
11
12package Mcrypt;
13
14require 5.004;
15require Exporter;
16require DynaLoader;
17require AutoLoader;
18use Carp;
19
20use strict;
21use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $AUTOLOAD);
22
23$VERSION = "2.5.7.0" ;
24
25@ISA = qw(Exporter DynaLoader);
26
27
28%EXPORT_TAGS = (
29		ALGORITHMS => [ qw(BLOWFISH
30				   DES
31				   3DES
32				   GOST
33				   CAST_128
34				   XTEA
35				   RC2
36				   TWOFISH
37				   CAST_256
38				   SAFERPLUS
39				   LOKI97
40				   SERPENT
41				   RIJNDAEL_128
42				   RIJNDAEL_192
43				   RIJNDAEL_256
44				   ENIGMA
45				   ARCFOUR
46				   WAKE) ],
47		MODES => [ qw(CBC
48			      ECB
49			      CFB
50			      OFB
51			      nOFB
52			      STREAM) ],
53		FUNCS => [ qw(mcrypt_load
54			      mcrypt_unload
55			      mcrypt_init
56			      mcrypt_end
57			      mcrypt_encrypt
58			      mcrypt_decrypt
59			      mcrypt_get_block_size
60			      mcrypt_get_iv_size
61			      mcrypt_get_key_size) ],
62	       );
63
64@EXPORT = qw( ERROR );
65
66@EXPORT_OK = qw(ERROR
67
68		BLOWFISH
69		DES
70		3DES
71		GOST
72		CAST_128
73		XTEA
74		RC2
75		TWOFISH
76		CAST_256
77		SAFERPLUS
78		LOKI97
79		SERPENT
80		RIJNDAEL_128
81		RIJNDAEL_192
82		RIJNDAEL_256
83		ENIGMA
84		ARCFOUR
85		WAKE
86
87		CBC
88		ECB
89		CFB
90		OFB
91		nOFB
92		STREAM
93
94		mcrypt_load
95		mcrypt_unload
96		mcrypt_init
97		mcrypt_end
98		mcrypt_encrypt
99		mcrypt_decrypt
100		mcrypt_get_block_size
101		mcrypt_get_iv_size
102		mcrypt_get_key_size);
103
104sub AUTOLOAD {
105    # This AUTOLOAD is used to 'autoload' constants from the constant()
106    # XS function.  If a constant is not found then control is passed
107    # to the AUTOLOAD in AutoLoader.
108
109    my $constname;
110    ($constname = $AUTOLOAD) =~ s/.*:://;
111    if($constname eq 'constant') {
112        # This will recurse!
113	croak "Problem loading Mcrypt libraries";
114    }
115    my $val = constant($constname, @_ ? $_[0] : 0);
116    if ($! != 0) {
117        if ($! =~ /Invalid/) {
118            $AutoLoader::AUTOLOAD = $AUTOLOAD;
119            goto &AutoLoader::AUTOLOAD;
120        }
121        else {
122                croak "Your vendor has not defined Mcrypt macro $constname";
123        }
124    }
125    eval "sub $AUTOLOAD { \"$val\" }";
126    goto &$AUTOLOAD;
127}
128
129bootstrap Mcrypt $VERSION ;
130
131sub new {
132  my($self, %arg) = @_;
133  my $class = ref($self) || $self;
134  return undef unless defined($arg{'algorithm'});
135  return undef  unless defined($arg{'mode'});
136  $arg{'algorithm_dir'} = '' unless defined($arg{'algorithm_dir'});
137  $arg{'mode_dir'} = '' unless defined($arg{'mode_dir'});
138  my $td = mcrypt_load( $arg{'algorithm'}, $arg{'algorithm_dir'},
139			$arg{'mode'}, $arg{'mode_dir'} );
140  my $mcrypt = bless { TD => $td }, $class;
141  $mcrypt->{Verbose} = 1;
142  $mcrypt->{Verbose} = $arg{'verbose'} if(defined($arg{'verbose'}));
143  $mcrypt->{KEY_SIZE} = mcrypt_get_key_size($td);
144  $mcrypt->{IV_SIZE} = mcrypt_get_iv_size($td);
145  $mcrypt->{BLOCK_SIZE} = -1; # default to not be in block mode
146  $mcrypt->{BLOCK_SIZE} = mcrypt_get_block_size($td)
147    if(mcrypt_is_block_algorithm_mode($td));
148  return $mcrypt;
149}
150
151sub init {
152  my($self, $key, $iv) = @_;
153  if($self->{Verbose}) {
154    print STDERR "Mcrypt: your initialization vector is the wrong length.\n"
155      if($self->{Verbose} &&
156	 ($self->{IV_SIZE} > 0) && ($self->{IV_SIZE} != length($iv)));
157  }
158  return ($self->{Initialized} = mcrypt_init($self->{TD}, $key, $iv));
159}
160
161sub end {
162  my($self) = shift;
163  my $ret = 0;
164  $ret = mcrypt_end($self->{TD})
165    if($self->{Initialized} && $self->{TD});
166  $self->{TD} = 0;
167  return $ret;
168}
169
170sub encrypt {
171  my($self, $input) = @_;
172  return undef unless($self->{Initialized});
173  if($self->{Verbose}) {
174    print STDERR
175      "Mcrypt: running block mode and your input is not a valid length.\n"
176	if($self->{Verbose} &&
177	   ($self->{BLOCK_SIZE} > 0) &&
178	   ($self->{BLOCK_SIZE} != length($input)));
179  }
180  return mcrypt_encrypt($self->{TD}, $input);
181}
182
183sub decrypt {
184  my($self, $input) = @_;
185  return undef unless($self->{Initialized});
186  if($self->{Verbose}) {
187    print STDERR
188      "Mcrypt: running block mode and your input is not a valid length.\n"
189	if($self->{Verbose} &&
190	   ($self->{BLOCK_SIZE} > 0) &&
191	   ($self->{BLOCK_SIZE} != length($input)));
192  }
193  return mcrypt_decrypt($self->{TD}, $input);
194}
195
196sub DESTROY {
197  my($self) = shift;
198  if($self->{Initialized}) {
199    $self->end();
200  } else {
201    mcrypt_unload($self->{TD});
202  }
203}
204
2051;
206
207__END__
208
209# Below is the stub of documentation for your module. You better edit it!
210
211=head1 NAME
212
213Mcrypt - Perl extension for the Mcrypt cryptography library
214
215=head1 SYNOPSIS
216
217  use Mcrypt;
218
219  # Procedural routines
220
221  $td = Mcrypt::mcrypt_load($algorithm, $algorithm_dir,
222			    $mode, $mode_dir);
223
224  Mcrypt::mcrypt_get_key_size($td);   # in bytes
225  Mcrypt::mcrypt_get_iv_size($td);    # in bytes
226  Mcrypt::mcrypt_get_block_size($td); # in bytes
227
228  Mcrypt::mcrypt_init($td, $key, $iv);
229
230  $encryptedstr = Mcrypt::mcrypt_encrypt($td, $decryptedstr);
231  $decryptedstr = Mcrypt::mcrypt_decrypt($td, $encryptedstr);
232
233  Mcrypt::mcrypt_end($td);
234
235  # Object-oriented methods
236
237  $td = Mcrypt->new( algorithm => $algorithm,
238		     mode => $mode );
239
240  $keysize = $td->{KEY_SIZE};
241  $ivsize  = $td->{IV_SIZE};
242  $blksize = $td->{BLOCK_SIZE};
243
244  $td->init($key, $iv);
245
246  $encryptedstr = $td->encrypt($decryptedstr);
247  $decryptedstr = $td->decrypt($encryptedstr);
248
249  # If the $td goes out of context,
250  # the destructor will do this for you
251  $td->end();
252
253=head1 DESCRIPTION
254
255This module wraps the libmcrypt encryption library for easy and convenient
256use from within perl.  Encryption and decryption using a variety of algorithms
257is as easy as a few simple lines of perl.
258
259=head1 Exported constants
260
261The predefined groups of exports in the use statements are as follows:
262
263use Mcrypt qw(:ALGORITHMS);
264
265Exports the BLOWFISH DES 3DES GOST
266CAST_128 XTEA RC2 TWOFISH CAST_256 SAFERPLUS LOKI97 SERPENT
267RIJNDAEL_128 RIJNDAEL_192 RIJNDAEL_256 ENIGMA ARCFOUR WAKE libmcrypt
268algorithms.  See the mcrypt(3) man page for more details.
269
270use Mcrypt qw(:MODES);
271
272Exports the CBC ECB CFB OFB bOFB STREAM modes of encryption.  See the
273mcrypt(3) man page for more details.
274
275use Mcrypt qw(:FUNCS);
276
277Exports the following functions: mcrypt_load, mcrypt_unload,
278mcrypt_init, mcrypt_end, mcrypt_encrypt, mcrypt_decrypt,
279mcrypt_get_block_size, mcrypt_get_iv_size, mcrypt_get_key_size.
280
281=head1 EXAMPLES
282
283  # Procedural approach:
284  # create an ecryption descriptor:
285  #   ALGORITHM: blowfish (256 bit key + 16 byte IV)
286  #   MODE:      cfb
287  # The user application has set:
288  #   $method to either "encrypt" or "decrypt"
289  #   $infile to the input filename
290  #   $outfile to the output filename
291  my($td) = Mcrypt::mcrypt_load( Mcrypt::BLOWFISH, '',
292				 Mcrypt::CFB, '' );
293  my($key) = "32 bytes of your apps secret key";  # secret key
294  my($iv) = "16 bytes of rand"; # shared initialization vector
295  Mcrypt::mcrypt_init($td, $key, $iv) || die "Could not initialize td";
296  print Mcrypt::mcrypt_encrypt($td, $_) while(<>);
297  Mcrypt::mcrypt_end($td);
298
299  # OO approach of the above except decrypting
300  my($td) = Mcrypt->new( algorithm => Mcrypt::BLOWFISH,
301                         mode => Mcrypt::CFB,
302                         verbose => 0 );
303  my($key) = "k" x $td->{KEY_SIZE};
304  my($iv) = "i" x $td->{IV_SIZE};
305  $td->init($key, $iv);
306  print $td->decrypt($_) while (<>);
307  $td->end();
308
309=head1 AUTHOR
310
311Theo Schlossnagle <jesus@omniti.com>
312
313=head1 SEE ALSO
314
315The libmcrypt man page: mcrypt(3).  Other libmcrypt information is
316available at http://mcrypt.hellug.gr/.
317
318=cut
319