Crypt-ECB-2.21/0000755€€Fü€€0000000000012771167770015345 5ustar SL-SI+cappelSL-SI+Domain UsersCrypt-ECB-2.21/ARTISTIC0000644€€Fü€€0000001373212760047506016510 0ustar SL-SI+cappelSL-SI+Domain Users The "Artistic License" Preamble The intent of this document is to state the conditions under which a Package may be copied, such that the Copyright Holder maintains some semblance of artistic control over the development of the package, while giving the users of the package the right to use and distribute the Package in a more-or-less customary fashion, plus the right to make reasonable modifications. Definitions: "Package" refers to the collection of files distributed by the Copyright Holder, and derivatives of that collection of files created through textual modification. "Standard Version" refers to such a Package if it has not been modified, or has been modified in accordance with the wishes of the Copyright Holder as specified below. "Copyright Holder" is whoever is named in the copyright or copyrights for the package. "You" is you, if you're thinking about copying or distributing this Package. "Reasonable copying fee" is whatever you can justify on the basis of media cost, duplication charges, time of people involved, and so on. (You will not be required to justify it to the Copyright Holder, but only to the computing community at large as a market that must bear the fee.) "Freely Available" means that no fee is charged for the item itself, though there may be fees involved in handling the item. It also means that recipients of the item may redistribute it under the same conditions they received it. 1. You may make and give away verbatim copies of the source form of the Standard Version of this Package without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. 2. You may apply bug fixes, portability fixes and other modifications derived from the Public Domain or from the Copyright Holder. A Package modified in such a way shall still be considered the Standard Version. 3. You may otherwise modify your copy of this Package in any way, provided that you insert a prominent notice in each changed file stating how and when you changed that file, and provided that you do at least ONE of the following: a) place your modifications in the Public Domain or otherwise make them Freely Available, such as by posting said modifications to Usenet or an equivalent medium, or placing the modifications on a major archive site such as uunet.uu.net, or by allowing the Copyright Holder to include your modifications in the Standard Version of the Package. b) use the modified Package only within your corporation or organization. c) rename any non-standard executables so the names do not conflict with standard executables, which must also be provided, and provide a separate manual page for each non-standard executable that clearly documents how it differs from the Standard Version. d) make other distribution arrangements with the Copyright Holder. 4. You may distribute the programs of this Package in object code or executable form, provided that you do at least ONE of the following: a) distribute a Standard Version of the executables and library files, together with instructions (in the manual page or equivalent) on where to get the Standard Version. b) accompany the distribution with the machine-readable source of the Package with your modifications. c) give non-standard executables non-standard names, and clearly document the differences in manual pages (or equivalent), together with instructions on where to get the Standard Version. d) make other distribution arrangements with the Copyright Holder. 5. You may charge a reasonable copying fee for any distribution of this Package. You may charge any fee you choose for support of this Package. You may not charge a fee for this Package itself. However, you may distribute this Package in aggregate with other (possibly commercial) programs as part of a larger (possibly commercial) software distribution provided that you do not advertise this Package as a product of your own. You may embed this Package's interpreter within an executable of yours (by linking); this shall be construed as a mere form of aggregation, provided that the complete Standard Version of the interpreter is so embedded. 6. The scripts and library files supplied as input to or produced as output from the programs of this Package do not automatically fall under the copyright of this Package, but belong to whoever generated them, and may be sold commercially, and may be aggregated with this Package. If such scripts or library files are aggregated with this Package via the so-called "undump" or "unexec" methods of producing a binary executable image, then distribution of such an image shall neither be construed as a distribution of this Package nor shall it fall under the restrictions of Paragraphs 3 and 4, provided that you do not represent such an executable image as a Standard Version of this Package. 7. C subroutines (or comparably compiled subroutines in other languages) supplied by you and linked into this Package in order to emulate subroutines and variables of the language defined by this Package shall not be considered part of this Package, but are the equivalent of input as in Paragraph 6, provided these subroutines do not change the language in any way that would cause it to fail the regression tests for the language. 8. Aggregation of this Package with a commercial distribution is always permitted provided that the use of this Package is embedded; that is, when no overt attempt is made to make this Package's interfaces visible to the end user of the commercial distribution. Such use shall not be construed as a distribution of this Package. 9. The name of the Copyright Holder may not be used to endorse or promote products derived from this software without specific prior written permission. 10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. The EndCrypt-ECB-2.21/CHANGES0000644€€Fü€€0000000612112771166150016327 0ustar SL-SI+cappelSL-SI+Domain Usersv2.21, 23.09.2016 - no code changes to ECB.pm - ecb.pl -l now prints module versions - ignoring Serpent in test suite as it is broken on many platforms v2.20, 30.03.2016 - made passing a custom padding method possible without specifying a cipher before - added verifying correct truncation of custom padding methods - added verifying padded bytes when truncating (for standard and zeroes padding) - added testing encrypt_hex and decrypt_hex function style - added testing start-crypt-finish - added testing usage of pre-existing cipher objects - updated eg/ecb.pl to recognize cipher modules in the Crypt::OpenSSL namespace - added option to eg/ecb.pl to print the Crypt::ECB version used - changed license again, to GPL or Artistic v2.15, 14.03.2016 - removing caching with v2.00 made Crypt::ECB ignorant of key changes within the same Crypt::ECB object. Fixed, changing the key now forces a new cipher object to be created. - added some notes on upgrading from versions before v2.00 to the README v2.10, 07.03.2016 - forgot another change in the v2.00 changelog... - changed license from GPL to Artistic - improved kwalitee: - added license information to meta files - removed test.pl - added eg/ecb.pl (command line en- and decryption) - added dummy cipher, so the test suite actually performs some tests even if there are no block ciphers installed - refactored test data from test scripts v2.05, 04.03.2016 - make Crypt:ECB work under perl-5.8.* again - some changes actually made in v2.00 haven't been mentioned in the changelog - add some more block ciphers to the test suite - minor changes in test.pl - minor documentation update v2.00, 19.02.2016 - ATTENTION, there are subtle changes in the API, see README for details - removed caching; the feature did finally not seem to make much sense - removed constants indicating the padding mode (PADDING_AUTO, PADDING_NONE) - removed errstring(), Crypt::CBC now dies when stumbling over errors - better compatibility with current Crypt::CBC: - allow passing options like Crypt::CBC does (new and old styles) - allow passing an existing cipher object (RT ticket #112020) - added padding styles, including custom padding - adding 'null' padding fixes RT ticket #80456 - added methods for accessing keysize and blocksize of a cipher - use Test::More (thanks to Xavier Guimard for providing a patch, RT ticket #82301) - changed internal attribute names (foo -> _foo and Foo -> foo) - much more internal code cleanup - updated documentation v1.45, 16.07.2008 - fixed test.pl so it will not stumble over an already installed Crypt::CBC - fixed bug in t/70-funcstyle.t which could in some cases let tests wrongly fail - test scripts: changed indentation, updated list of known ciphers v1.40, 07.01.2005 - the '0' block problem still had survived in functions encrypt and decrypt... fixed - some code cleanup - changed versioning scheme to be more CPAN-like v1.3, 06.01.2005 - no code changes, just some minor documentation update v1.2, 06.01.2005 - fixed problems with blocks consisting of a '0' v1.1, 23.12.2000 - first release Crypt-ECB-2.21/ECB.pm0000644€€Fü€€0000005241712771166510016274 0ustar SL-SI+cappelSL-SI+Domain Userspackage Crypt::ECB; # Copyright (C) 2000, 2005, 2008, 2016 Christoph Appel (Christoph.Appel@t-systems.com) # see documentation for details ######################################## # general module startup things ######################################## use strict; use warnings; use vars qw(@ISA @EXPORT @EXPORT_OK $VERSION); require Exporter; @ISA = qw(Exporter); @EXPORT_OK = qw(encrypt decrypt encrypt_hex decrypt_hex); $VERSION = '2.21'; ######################################## # public methods - setting up ######################################## # # constructor, initialization of vars # sub new ($;$$$) { my $class = shift; my $self = { padding => 'standard', # default padding method mode => '', key => '', cipher => '', module => '', keysize => '', blocksize => '', _cipherobj => '', # contains the block cipher object _buffer => '', # internal buffer used by crypt() and finish() }; bless $self, $class; if ($_[0]) { my $options; # options Crypt::CBC style if ($_[0] =~ /^-[a-zA-Z]+$/) { my %tmp = @_; $options->{substr(lc $_, 1)} = $tmp{$_} for keys %tmp; } # options like in Crypt::CBC before 2.13 elsif (ref $_[0] eq 'HASH') { $options = shift; } # and like Crypt::CBC before 2.0 else { $options->{key} = shift; $options->{cipher} = shift || 'DES'; } # cipher has to be called before keysize and blocksize # otherwise it would override values provided by the user $self->$_( $options->{$_} ) foreach qw(cipher keysize key blocksize padding); } return $self; } # # set attributes if argument given, return attribute value # sub module (\$) { return $_[0]->{module} } sub keysize (\$;$) { $_[0]->{keysize} = $_[1] if $_[1]; return $_[0]->{keysize} } sub blocksize (\$;$) { $_[0]->{blocksize} = $_[1] if $_[1]; return $_[0]->{blocksize} } sub mode (\$) { return $_[0]->{mode} } # # sets key if argument given # sub key (\$;$) { my $self = shift; if (my $key = shift) { $self->{key} = $key; # forget cipher object to force creating a new one # otherwise a key change would not be recognized $self->{_cipherobj} = ''; } return $self->{key}; } # # sets padding method if argument given # sub padding (\$;$) { my $self = shift; if (my $padding = shift) { # if given a custom padding... if (ref $padding eq 'CODE') { # ...for different block sizes... for my $bs ((8, 16)) { # ...check whether it works as expected for my $i (0 .. $bs-1) { my $plain = ' ' x $i; my $padded = $padding->($plain, $bs, 'e') || ''; die "Provided padding method does not pad properly: Expected $bs bytes, got ", length $padded, ".\n" unless (length $padded == $bs); my $trunc = $padding->($padded, $bs, 'd') || ''; die "Provided padding method does not truncate properly: Expected '$plain', got '$trunc'.\n" unless ($trunc eq $plain); } } } $self->{padding} = $padding; } return $self->{padding}; } # # sets and loads crypting module if argument given # sub cipher (\$;$) { my $self = shift; if (my $cipher = shift) { my $module; # if a cipher object is provided... if (ref $cipher) { # ...use it $self->{_cipherobj} = $cipher; $module = ref $cipher; ($cipher = $module) =~ s/^Crypt:://; } # else try to load the specified cipher module else { # for compatibility with Crypt::CBC, cipher modules can be specified # with or without the 'Crypt::' in front $module = $cipher=~/^Crypt/ ? $cipher : "Crypt::$cipher"; eval "require $module"; die "Couldn't load $module: $@"."Are you sure '$cipher' is correct? If so," . " install $module in the proper path or choose some other cipher.\n" if $@; # delete possibly existing cipher obj from a previous crypt process # otherwise changes in the cipher would not be recognized by start() $self->{_cipherobj} = ''; } # some packages like Crypt::DES and Crypt::IDEA behave strange in the way # that their methods do not belong to the Crypt::DES or Crypt::IDEA namespace # but only DES or IDEA instead unless ($module->can('blocksize')) { $module=$cipher } die "Can't work because Crypt::$cipher doesn't report blocksize." . " Are you sure $cipher is a valid cipher module?\n" unless ($module->can('blocksize') && $module->blocksize); $self->{blocksize} = $module->blocksize; # In opposition to the blocksize, the keysize need not be known by me, # but by the one who provides the key. This is because some modules # (e.g. Crypt::Blowfish) report keysize 0; in other cases several keysizes # are admitted, so reporting just one number would anyway be to narrow $self->{keysize} = $module->can('keysize') ? $module->keysize : ''; $self->{module} = $module; $self->{cipher} = $cipher; } return $self->{cipher}; } ######################################## # public methods - en-/decryption ######################################## # # sets mode if argument given, either en- or decrypt # checks, whether all required vars are set # returns mode # sub start (\$$) { my $self = shift; my $mode = shift; die "Not yet finished existing crypting process. Call finish() before calling start() anew.\n" if $self->{_buffer}; die "Mode has to be either (e)ncrypt or (d)ecrypt.\n" unless ($mode=~/^[de]/i); # unless a cipher object is provided (see cipher())... unless ($self->{_cipherobj}) { # make sure we have a key... die "Key not set. Use '\$ecb->key ('some_key'). The key length is probably specified" . " by the algorithm (for example the Crypt::IDEA module needs a sixteen byte key).\n" unless $self->{key}; # ...as well as a block cipher die "Can't start() without cipher. Use '\$ecb->cipher(\$cipher)', \$cipher being some" . " algorithm like for example 'DES', 'IDEA' or 'Blowfish'. Of course, the corresponding" . " module 'Crypt::\$cipher' needs to be installed.\n" unless $self->{module}; # initialize cipher obj doing the actual en-/decryption $self->{_cipherobj} = $self->{module}->new( $self->{key} ); } $self->{mode} = ($mode=~/^d/i) ? "decrypt" : "encrypt"; return $self->{mode}; } # # calls the crypting module # returns the en-/decrypted data # sub crypt (\$;$) { my $self = shift; my $data = shift; $data = ($_ || '') unless defined $data; my $bs = $self->{blocksize}; my $mode = $self->{mode}; die "You tried to use crypt() without calling start() before. Use '\$ecb->start(\$mode)'" . " first, \$mode being one of 'decrypt' or 'encrypt'.\n" unless $mode; $data = $self->{_buffer}.$data; # data is split into blocks of proper size which is reported # by the cipher module my @blocks = $data=~/(.{1,$bs})/gs; # last block goes into buffer $self->{_buffer} = pop @blocks; my ($cipher, $text) = ($self->{_cipherobj}, ''); $text .= $cipher->$mode($_) foreach (@blocks); return $text; } # # # sub finish (\$) { my $self = shift; my $bs = $self->{blocksize}; my $mode = $self->{mode}; my $data = $self->{_buffer}; my $result = ''; die "You tried to use finish() without calling start() before. Use '\$ecb->start(\$mode)'" . " first, \$mode being one of 'decrypt' or 'encrypt'.\n" unless $mode; # cleanup: forget mode, purge buffer $self->{mode} = ''; $self->{_buffer} = ''; return '' unless defined $data; my $cipher = $self->{_cipherobj}; # now we have to distinguish between en- and decryption: # when decrypting, data has to be truncated to correct size # when encrypting, data has to be padded up to blocksize if ($mode =~ /^d/i) { # pad data with binary 0 up to blocksize # in fact, this should not be necessary because correctly # encrypted data is always a multiple of the blocksize $data = pack("a$bs",$data); $result = $cipher->$mode($data); $result = $self->_truncate($result); } else { # if length is smaller than blocksize, just pad the block if (length($data) < $bs) { $data = $self->_pad($data); $result = $cipher->$mode($data); } # else append another block (depending on padding chosen) else { $result = $cipher->$mode($data); $self->_pad('') && ($result .= $cipher->$mode( $self->_pad('') )); } } return $result; } ######################################## # private methods ######################################## # # pad block to blocksize # sub _pad (\$$) { my $self = shift; my $data = shift; my $bs = $self->{blocksize}; my $padding = $self->{padding}; my $pad = $bs - length $data; my $message = "Your message length is not a multiple of $self->{cipher}'s blocksize ($bs bytes)." . " Correct this by hand or tell me to handle padding.\n"; $padding eq 'standard' ? $data .= chr($pad) x $pad : $padding eq 'zeroes' ? $data .= "\0" x ($pad-1) . chr($pad) : $padding eq 'oneandzeroes' ? $data .= "\x80" . "\0"x($pad-1) : $padding eq 'rijndael_compat' ? (length $data) && ($data .= "\x80" . "\0"x($pad-1)) : $padding eq 'null' ? $data .= "\0"x $pad : $padding eq 'space' ? (length $data) && ($data .= " " x $pad) : ref $padding eq 'CODE' ? $data = $padding ->($data, $bs, 'e') : $padding eq 'none' ? (length($data) % $bs) && die $message : # still here? die "Padding style '$padding' not defined.\n"; return $data; } # # truncates result to correct length # sub _truncate (\$$) { my $self = shift; my $data = shift; my $bs = $self->{blocksize}; my $padding = $self->{padding}; if ($padding =~ /^(standard|zeroes|random)$/) { my $trunc = ord(substr $data, -1); die "Asked to truncate $trunc bytes, which is greater than $self->{cipher}'s blocksize ($bs bytes).\n" if $trunc > $bs; my $expected = $padding eq 'standard' ? chr($trunc) x $trunc : $padding eq 'zeroes' ? "\0" x ($trunc-1) . chr($trunc) : $padding eq 'random' ? substr($data, -$trunc, $trunc-1) . chr($trunc) : 'WTF!?'; die "Block doesn't look $padding padded.\n" unless $expected eq substr($data, -$trunc); substr($data, -$trunc) = ''; } else { $padding eq 'oneandzeroes' ? $data =~ s/\x80\0*$//s : $padding eq 'rijndael_compat' ? $data =~ s/\x80\0*$//s : $padding eq 'null' ? $data =~ s/\0+$//s : $padding eq 'space' ? $data =~ s/ +$//s : ref $padding eq 'CODE' ? $data = $padding->($data, $bs, 'd') : $padding eq 'none' ? () : # still here? die "Padding style '$padding' not defined.\n"; } return $data; } ######################################## # convenience functions/methods ######################################## # # magic decrypt/encrypt function/method # sub _crypt { my ($mode, $self, $key, $cipher, $data, $padding); if (ref $_[1]) { ($mode, $self, $data) = @_; } else { ($mode, $key, $cipher, $data, $padding) = @_; $self = __PACKAGE__->new($key => $cipher); $self->padding($padding) if $padding; $data = $_ unless length($data); } $self->start($mode); my $text = $self->crypt($data) . $self->finish; return $text; } # # convenience encrypt and decrypt functions/methods # sub encrypt ($$;$$) { _crypt('encrypt', @_) } sub decrypt ($$;$$) { _crypt('decrypt', @_) } # # calls encrypt, returns hex packed data # sub encrypt_hex ($$;$$) { if (ref $_[0]) { my $self = shift; join('',unpack('H*',$self->encrypt(shift))); } else { join('',unpack('H*',encrypt($_[0], $_[1], $_[2], $_[3]))); } } # # calls decrypt, expected input is hex packed # sub decrypt_hex ($$;$$) { if (ref $_[0]) { my $self = shift; $self->decrypt(pack('H*',shift)); } else { decrypt($_[0], $_[1], pack('H*',$_[2]), $_[3]); } } ######################################## # finally, to satisfy require ######################################## 'The End...'; __END__ =head1 NAME Crypt::ECB - Use block ciphers using ECB mode =head1 SYNOPSIS Use Crypt::ECB OO style use Crypt::ECB; $ecb = Crypt::ECB->new; $ecb->cipher('Blowfish'); $ecb->key('some_key'); $enc = $ecb->encrypt("Some data."); print $ecb->decrypt($enc); or use the function style interface use Crypt::ECB qw(encrypt decrypt encrypt_hex decrypt_hex); $ciphertext = encrypt($key, 'Blowfish', "Some data"); $plaintext = decrypt($key, 'Blowfish', $ciphertext); $hexcode = encrypt_hex($key, $cipher, $plaintext); $plain = decrypt_hex($key, $cipher, $hexcode); =head1 DESCRIPTION This module is a Perl-only implementation of the ECB mode. In combination with a block cipher such as Blowfish, DES, IDEA or Rijndael, you can encrypt and decrypt messages of arbitrarily long length. Though for security reasons other modes than ECB such as CBC should be preferred. See textbooks on cryptography if you want to know why. The functionality of the module can be accessed via OO methods or via standard function calls. Remember that some block cipher module like for example Crypt::Blowfish has to be installed. The syntax of Crypt::ECB follows that of Crypt::CBC. =head1 METHODS =head2 new() $ecb = Crypt::ECB->new( -cipher => $cipher, -key => $key, -padding => 'oneandzeroes', -keysize => 8, # use to override cipher's default -blocksize => 8, # use to override cipher's default ); or $ecb = Crypt::ECB->new({ cipher => $cipher, key => $key, padding => 'oneandzeroes', keysize => 8, # use to override cipher's default blocksize => 8, # use to override cipher's default }); or (only key and cipher can be passed this way) $ecb = Crypt::ECB->new($key, 'Blowfish'); $ecb = Crypt::ECB->new($key); # DES is assumed The following options are recognized: cipher, key, keysize, blocksize and padding. Options can be passed like in Crypt::CBC. All options can be read and also be changed via corresponding methods afterwards. If called without parameters you have to call at least B and B before you can start crypting. =head2 cipher(), module(), key() $ecb = Crypt::ECB->new; $ecb->cipher('Blowfish'); $ecb->key('some_key'); print $ecb->cipher; # Blowfish print $ecb->module; # Crypt::Blowfish print $ecb->key; # some_key or my $ecb = Crypt::ECB->new; my $xtea = Crypt::XTEA->new($key, 32, little_endian => 1); $ecb->cipher($xtea); B sets the block cipher to be used. It tries to load the corresponding module. If an error occurs, it dies with some errmessage. Otherwise it returns the cipher name. Free packages available for Perl are for example Blowfish, DES, IDEA or Rijndael. If called without parameter it just returns the name of the cipher. B also accepts a pre-existing object from a suitable block cipher module. This is useful e.g. for cipher modules such as Crypt::XTEA which need additional parameters. B returns the perl package containing the block cipher which has been specified using cipher(). B sets the key if given a parameter. It always returns the key. Note that most block ciphers require keys of definite length. For example DES expects an eight byte key. =head2 keysize(), blocksize() $ecb = Crypt::ECB->new; $ecb->cipher('Blowfish'); $keysize = $ecb->keysize; $blocksize = $ecb->blocksize; These methods can be used to retrieve keysize and blocksize as reported from the block cipher chosen. They can be used as well to override the values that are reported from the cipher module. Of course that doesn't make sense unless the block cipher used supports the new values. E.g. Crypt::Rijndael works with 16, 24 and 32 byte keys. =head2 padding() $ecb->padding('oneandzeroes'); my $custom_padding = sub { ... }; $ecb->padding($custom_padding); B sets the way how data is padded up to a multiple of the cipher's blocksize. Until now the following methods are implemented: 'standard', 'zeroes', 'oneandzeroes', 'rijndael_compat', 'space', 'null' and 'none'. If the padding style is not set explicitly, 'standard' is used. 'standard' (default) (binary safe) The PKCS#5 / PKCS#7 method (RFC 5652): Pads with the number of bytes that should be truncated. So, if blocksize is 8, then "0A0B0C" will be padded with five "05"s, resulting in "0A0B0C0505050505". If the message is already a multiple of the cipher's block size, then another whole block is appended. 'zeroes' (binary safe) This is a variant of the standard method. It pads with null bytes, except the last byte equals the number of padding bytes. So, if the blocksize is 8, then "0A0B0C" will be padded to "0A0B0C0000000005". If the message is already a multiple of the cipher's block size, then another whole block is appended. 'oneandzeroes' (binary safe) Pads with "80" followed by as many "00"s as necessary to fill the block, in other words a 1 bit followed by 0s. If the message already is a multiple of the cipher's block size, then another whole block is appended. 'rijndael_compat' (binary safe) Similar to oneandzeroes, except that no padding is performed if the message already is already a multiple of the cipher's block size. This is provided for compatibility with Crypt::Rijndael. 'null' Pads with as many null bytes as necessary to fill the block. If the message is already a multiple of the cipher's block size, then another whole block is appended. ATTENTION: Can truncate more characters than it should (if the original message ended with one or more null bytes). 'space' Pads with as many space characters as necessary to fill the block. If the message is already a multiple of the cipher's block size, unlike the other methods NO block is appended. ATTENTION: Can truncate more characters than it should (if the original message ended with one or more space characters). 'none' No padding added by Crypt::ECB. You then have to take care of correct padding and truncating yourself. You can also use a custom padding function. To do this, create a function that is called like: $padded_block = function($block, $blocksize, $direction); and tell Crypt::ECB to use your function: $ecb->padding(\&function); $block is the current block of data, $blocksize is the size to pad to, $direction is "e" for encrypting and "d" for decrypting, and $padded_block is the result after padding or truncation. When encrypting, the function should always return a string of $blocksize length, and when decrypting, it can expect the string coming in to be of that length. =head2 start(), mode(), crypt(), finish() $ecb->start('encrypt'); $enc .= $ecb->crypt($_) foreach (@lines); $enc .= $ecb->finish; $ecb->start('decrypt'); print $ecb->mode; B sets the crypting mode, checks if all required variables like key and cipher are set, then initializes the block cipher specified. Allowed parameters are any words starting either with 'e' or 'd'. The method returns the current mode. B is called without parameters and just returns the current mode. B processes the data given as argument. If called without argument $_ is processed. The method returns the processed data. Cipher and key have to be set in order to be able to process data. If some of these are missing or B was not called before, the method dies. After having sent all data to be processed to B you have to call B in order to flush data that's left in the buffer. =head2 encrypt(), decrypt(), encrypt_hex(), decrypt_hex() $enc = $ecb->encrypt($data); print $ecb->decrypt($enc); $hexenc = $ecb->encrypt_hex($data); print $ecb->decrypt_hex($hexenc); B and B are convenience methods which call B, B and B for you. B and B are convenience functions that operate on ciphertext in a hexadecimal representation. These functions can be useful if, for example, you wish to place the encrypted information into an e-mail message, web page or URL. =head1 FUNCTIONS For convenience en- or decrypting can also be done by calling ordinary functions. The functions are: B, B, B, B. =head2 encrypt(), decrypt(), encrypt_hex(), decrypt_hex() use Crypt::ECB qw(encrypt decrypt encrypt_hex decrypt_hex); $ciphertext = encrypt($key, $cipher, $plaintext, $padstyle); $plaintext = decrypt($key, $cipher, $ciphertext, $padstyle); $ciphertext = encrypt_hex($key, $cipher, $plaintext, $padstyle); $plaintext = decrypt_hex($key, $cipher, $ciphertext, $padstyle); B and B process the provided text and return either the corresponding ciphertext (encrypt) or plaintext (decrypt). Data and padstyle are optional. If the padding style is omitted, 'standard' is assumed. If data is omitted, $_ is used. B and B operate on ciphertext in a hexadecimal representation, just like the methods with the same name, see above. Otherwise usage is the same as for B and B. =head1 BUGS None that I know of. Please report if you find any. =head1 TODO Implement 'random' padding, see http://www.di-mgt.com.au/cryptopad.html. A taint check on the key like Crypt::CBC does could be added. =head1 LICENSE Crypt-ECB is Copyright (C) 2000, 2005, 2008, 2016 by Christoph Appel. This module is distributed using the same terms as Perl itself. It is free software; you can redistribute it and/or modify it under the terms of either: a) the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version, or b) the "Artistic License". =head1 AUTHOR Christoph Appel (see ECB.pm for email address) =head1 SEE ALSO perl(1), Crypt::DES(3), Crypt::IDEA(3), Crypt::CBC(3) =cut Crypt-ECB-2.21/eg/0000755€€Fü€€0000000000012771167757015745 5ustar SL-SI+cappelSL-SI+Domain UsersCrypt-ECB-2.21/eg/ecb.pl0000755€€Fü€€0000000430712771165717017034 0ustar SL-SI+cappelSL-SI+Domain Users#!/usr/bin/perl -w use Getopt::Std; use Crypt::ECB; use strict; my $usage = "Usage: ecb.pl [-d] [-c ] [-p ] [-k ] [-f ] or ecb.pl -l or ecb.pl -v Encrypt/decrypt files using ECB mode. Reads from STDIN, writes to STDOUT. Options: -l list available ciphers -d decrypt (default mode is encrypt) -k key to use -f file containing key; either -k or -f must be specified -c block cipher to use, defaults to 'Rijndael' (AES) -p padding mode to use, possible values are 'standard' (default), 'zeroes', 'oneandzeroes', 'rijndael_compat', 'null', 'space' and 'none'. See Crypt::ECB for details on the different modes. -v print Crypt::ECB version "; my $version = "Using Crypt::ECB version $Crypt::ECB::VERSION.\n"; my $options = {}; getopts('vldc:p:k:f:', $options) || die $usage; print($version), exit(0) if $options->{v}; list_ciphers(), exit(0) if $options->{l}; die $usage unless $options->{k} or $options->{f}; sub slurp { open(F,$_[0]) || die "Couldn't open $_[0]: $!\n"; local $/; return } my $key = $options->{k} || slurp($options->{f}); my $cipher = $options->{c} || 'Rijndael'; # AES my $padding = $options->{p} || 'standard'; my $mode = $options->{d} ? 'decrypt' : 'encrypt'; my $ecb = Crypt::ECB->new(-key => $key, -cipher => $cipher, -padding => $padding); $ecb->start($mode); print $ecb->crypt while read(STDIN, $_, 1024); print $ecb->finish; exit(0); sub list_ciphers { print "Checking your perl installation for block ciphers compliant with Crypt::ECB...\n"; my ($ecb, $ok) = (Crypt::ECB->new, 0); close STDERR; # avoid strange error messages from modules tried foreach my $path (@INC) { while (<$path/Crypt/*.pm $path/Crypt/*/*.pm>) { next unless /\.pm$/; s|^.*Crypt/||; s|\.pm$||; s|/|::|g; eval { $ecb->cipher($_) }; printf(" found %-25s (keysize: %2s, blocksize: %2s)\n", "$_ ".$ecb->module->VERSION, $ecb->keysize, $ecb->blocksize) if !$@ and ++$ok; } } print "There do not seem to be any block ciphers installed (at least none which I can\n" . "use). Crypt::ECB will not be of any use to you unless you install some suitable\n" . "cipher module(s).\n" unless $ok; } Crypt-ECB-2.21/GPLv10000644€€Fü€€0000002333012760047510016145 0ustar SL-SI+cappelSL-SI+Domain Users GNU GENERAL PUBLIC LICENSE Version 1, February 1989 Copyright (C) 1989 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The license agreements of most software companies try to keep users at the mercy of those companies. By contrast, our General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. The General Public License applies to the Free Software Foundation's software and to any other program whose authors commit to using it. You can use it for your programs, too. When we speak of free software, we are referring to freedom, not price. Specifically, the General Public License is designed to make sure that you have the freedom to give away or sell copies of free software, that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of a such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must tell them their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any work containing the Program or a portion of it, either verbatim or with modifications. Each licensee is addressed as "you". 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this General Public License and to the absence of any warranty; and give any other recipients of the Program a copy of this General Public License along with the Program. You may charge a fee for the physical act of transferring a copy. 2. You may modify your copy or copies of the Program or any portion of it, and copy and distribute such modifications under the terms of Paragraph 1 above, provided that you also do the following: a) cause the modified files to carry prominent notices stating that you changed the files and the date of any change; and b) cause the whole of any work that you distribute or publish, that in whole or in part contains the Program or any part thereof, either with or without modifications, to be licensed at no charge to all third parties under the terms of this General Public License (except that you may choose to grant warranty protection to some or all third parties, at your option). c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the simplest and most usual way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this General Public License. d) You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. Mere aggregation of another independent work with the Program (or its derivative) on a volume of a storage or distribution medium does not bring the other work under the scope of these terms. 3. You may copy and distribute the Program (or a portion or derivative of it, under Paragraph 2) in object code or executable form under the terms of Paragraphs 1 and 2 above provided that you also do one of the following: a) accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Paragraphs 1 and 2 above; or, b) accompany it with a written offer, valid for at least three years, to give any third party free (except for a nominal charge for the cost of distribution) a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Paragraphs 1 and 2 above; or, c) accompany it with the information you received as to where the corresponding source code may be obtained. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form alone.) Source code for a work means the preferred form of the work for making modifications to it. For an executable file, complete source code means all the source code for all modules it contains; but, as a special exception, it need not include source code for modules which are standard libraries that accompany the operating system on which the executable file runs, or for standard header files or definitions files that accompany that operating system. 4. You may not copy, modify, sublicense, distribute or transfer the Program except as expressly provided under this General Public License. Any attempt otherwise to copy, modify, sublicense, distribute or transfer the Program is void, and will automatically terminate your rights to use the Program under this License. However, parties who have received copies, or rights to use copies, from you under this General Public License will not have their licenses terminated so long as such parties remain in full compliance. 5. By copying, distributing or modifying the Program (or any work based on the Program) you indicate your acceptance of this license to do so, and all its terms and conditions. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. 7. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of the license which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the license, you may choose any version ever published by the Free Software Foundation. 8. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONSCrypt-ECB-2.21/Makefile.PL0000644€€Fü€€0000000032512760047712017306 0ustar SL-SI+cappelSL-SI+Domain Usersuse ExtUtils::MakeMaker; WriteMakefile ( ABSTRACT_FROM => 'ECB.pm', AUTHOR => 'Christoph Appel', LICENSE => 'perl_5', MIN_PERL_VERSION => '5.6.0', NAME => 'Crypt::ECB', VERSION_FROM => 'ECB.pm', ); Crypt-ECB-2.21/MANIFEST0000644€€Fü€€0000000114112771167661016472 0ustar SL-SI+cappelSL-SI+Domain UsersARTISTIC CHANGES ECB.pm eg/ecb.pl GPLv1 Makefile.PL MANIFEST This list of files patches/XTEA-0.0107.patch patches/XTEA_PP-0.0106.patch README README.XTEA t/10-options.t t/15-sanity.t t/20-encryption.t t/25-decryption.t t/30-start-crypt-finish.t t/35-keychange.t t/40-padding.t t/45-padding-custom.t t/50-padding-fullblock.t t/60-substrings+nulls.t t/80-preexisting.t t/85-preexisting-xtea.t t/90-funcstyle.t t/Crypt/Dummy.pm t/Testdata.pm META.yml Module YAML meta-data (added by MakeMaker) META.json Module JSON meta-data (added by MakeMaker) Crypt-ECB-2.21/META.json0000644€€Fü€€0000000153712771167770016774 0ustar SL-SI+cappelSL-SI+Domain Users{ "abstract" : "Use block ciphers using ECB mode", "author" : [ "Christoph Appel" ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 7.0401, CPAN::Meta::Converter version 2.150001", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "Crypt-ECB", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "runtime" : { "requires" : { "perl" : "5.006000" } } }, "release_status" : "stable", "version" : "2.21" } Crypt-ECB-2.21/META.yml0000644€€Fü€€0000000074512771167762016625 0ustar SL-SI+cappelSL-SI+Domain Users--- abstract: 'Use block ciphers using ECB mode' author: - 'Christoph Appel' build_requires: ExtUtils::MakeMaker: '0' configure_requires: ExtUtils::MakeMaker: '0' dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 7.0401, CPAN::Meta::Converter version 2.150001' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Crypt-ECB no_index: directory: - t - inc requires: perl: '5.006000' version: '2.21' Crypt-ECB-2.21/patches/0000755€€Fü€€0000000000012771167757017001 5ustar SL-SI+cappelSL-SI+Domain UsersCrypt-ECB-2.21/patches/XTEA-0.0107.patch0000644€€Fü€€0000000050012666242563021271 0ustar SL-SI+cappelSL-SI+Domain Users--- XTEA.orig.pm 2016-02-17 04:53:07.000000000 +0100 +++ XTEA.pm 2016-03-04 10:19:52.374916400 +0100 @@ -23,10 +23,10 @@ my $ELEMENTS_IN_BLOCK = $BLOCK_SIZE / 4; -use constant keysize => $KEY_SIZE; +sub keysize { $KEY_SIZE } -use constant blocksize => $BLOCK_SIZE; +sub blocksize { $BLOCK_SIZE } sub new { Crypt-ECB-2.21/patches/XTEA_PP-0.0106.patch0000644€€Fü€€0000000050612666242600021665 0ustar SL-SI+cappelSL-SI+Domain Users--- XTEA_PP.orig.pm 2015-04-13 15:09:56.000000000 +0200 +++ XTEA_PP.pm 2016-03-04 10:20:15.487604900 +0100 @@ -30,10 +30,10 @@ my $ELEMENTS_IN_BLOCK = $BLOCK_SIZE / 4; -use constant keysize => $KEY_SIZE; +sub keysize { $KEY_SIZE } -use constant blocksize => $BLOCK_SIZE; +sub blocksize { $BLOCK_SIZE } sub new { Crypt-ECB-2.21/README0000644€€Fü€€0000000447512760051003016212 0ustar SL-SI+cappelSL-SI+Domain UsersModule Crypt::ECB ----------------- DESCRIPTION This module is a Perl-only implementation of the ECB mode. In combination with a block cipher such as DES, IDEA or Blowfish, you can encrypt and decrypt messages of arbitrarily long length. Though for security reasons other modes than ECB such as CBC should be preferred. See textbooks on cryptography if you want to know why. The functionality of the module can be accessed via OO methods or via standard function calls. Remember that some crypting module like for example Blowfish has to be installed. The syntax follows that of Crypt::CBC. INSTALLATION To install, just type perl Makefile.PL make make test make install If you are on a MS system, you possibly won't have make. But don't worry, installation is trivial as there is nothing to be compiled: Just create a directory 'Crypt' in Perl's libpath if not existing. Then copy 'ECB.pm' to that directory, that's all. Perl's libpath will be something like 'c:\perl\site\lib'. UPGRADING Eight years after the last release I thought it was okay to make a major upgrade. Which makes subtle changes to the API. So, if you are upgrading from a version below 2.00, be aware that the API has changed: - The caching feature is no longer available. Contact me if you really think you need it. - As I thought that exporting global constants isn't that nice and also in order to be more compatible with Crypt::CBC I changed the way that padding() is called: $ecb->padding(PADDING_AUTO) should be replaced by $ecb->padding('standard') (or could be omitted, because this is the default for Crypt-ECB-2.00 and later). $ecb->padding(PADDING_NONE) should be replaced by $ecb->padding('none'). $ecb->padding('none') is also needed if no padding was specified, because no padding was the default for versions before v2.00. - Exception handling is more perl-like. Crypt::ECB now dies when stumbling over errors. If you don't want that, catch it with an eval. COPYING Crypt-ECB is Copyright (C) 2000, 2005, 2008, 2016 by Christoph Appel. This module is distributed using the same terms as Perl itself. It is free software; you can redistribute it and/or modify it under the terms of either: a) the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version, or b) the "Artistic License". Crypt-ECB-2.21/README.XTEA0000644€€Fü€€0000000135012667543173016763 0ustar SL-SI+cappelSL-SI+Domain UsersThere are two modules implementing the XTEA block cipher, Crypt-XTEA and Crypt-XTEA_PP. In their current versions, as of March 2016 that is Crypt-XTEA-0.0107 and Crypt-XTEA_PP-0.0106, the way blocksize() and keysize() are implemented, they don't work on my platform (perl 5.22.1 on cygwin64 on Windows 7). blocksize() and keysize() are implemented as constants with values $KEY_SIZE and $BLOCK_SIZE. Now it seems to me, they are defined before $KEY_SIZE and $BLOCK_SIZE are initialized. This results in returning undef whenever Crypt::ECB calls keysize() or blocksize(). I have provided small patches which replace "use constant keysize => $KEY_SIZE" with "sub keysize { $KEY_SIZE }" (and the same for blocksize), like other cipher modules do. Crypt-ECB-2.21/t/0000755€€Fü€€0000000000012771167757015615 5ustar SL-SI+cappelSL-SI+Domain UsersCrypt-ECB-2.21/t/10-options.t0000644€€Fü€€0000000403012670215542017670 0ustar SL-SI+cappelSL-SI+Domain Users#!/usr/bin/perl -w use lib 't'; use Testdata; use Test::More tests => 15*@ciphers + 4; BEGIN { use_ok (Crypt::ECB) } my $ecb = Crypt::ECB->new; eval { $ecb->cipher('DES') }; SKIP: { skip "'DES' not installed", 3 if $@; $ecb = Crypt::ECB->new($key); ok($ecb->key eq $key, "DES, options very old style: key"); ok($ecb->cipher eq 'DES', "DES, options very old style: cipher"); ok($ecb->padding eq 'standard', "DES, options very old style: padding"); } foreach my $cipher (@ciphers) { eval { $ecb->cipher($cipher) }; SKIP: { skip "$cipher not installed", 15 if $@; $ecb = Crypt::ECB->new($key => $cipher); ok($ecb->key eq $key, "$cipher, options very old style: key"); ok($ecb->cipher eq $cipher, "$cipher, options very old style: cipher"); ok($ecb->padding eq 'standard', "$cipher, options very old style: padding"); $ecb = Crypt::ECB->new( {key => $key, cipher => $cipher, padding => 'oneandzeroes'} ); ok($ecb->key eq $key, "$cipher, options old style: key"); ok($ecb->cipher eq $cipher, "$cipher, options old style: cipher"); ok($ecb->padding eq 'oneandzeroes', "$cipher, options old style: padding"); $ecb = Crypt::ECB->new(-key => $key, -cipher => $cipher, -padding => 'oneandzeroes'); ok($ecb->key eq $key, "$cipher, options new style: key"); ok($ecb->cipher eq $cipher, "$cipher, options new style: cipher"); ok($ecb->padding eq 'oneandzeroes', "$cipher, options new style: padding"); $ecb = Crypt::ECB->new(-cipher => $cipher); ok($ecb->cipher eq $cipher, "$cipher, options new style: cipher"); ok($ecb->keysize == $ecb->module->keysize, "$cipher, options new style: keysize"); ok($ecb->blocksize == $ecb->module->blocksize, "$cipher, options new style: blocksize"); $ecb = Crypt::ECB->new(-cipher => $cipher, -keysize => 10, -blocksize => 10); ok($ecb->cipher eq $cipher, "$cipher, options new style: cipher"); ok($ecb->keysize == 10, "$cipher, options new style: keysize override"); ok($ecb->blocksize == 10, "$cipher, options new style: blocksize override"); } } Crypt-ECB-2.21/t/15-sanity.t0000644€€Fü€€0000000471212676745513017534 0ustar SL-SI+cappelSL-SI+Domain Users#!/usr/bin/perl -w use lib 't'; use Testdata; use Test::More tests => 11*@ciphers + 3; BEGIN { use_ok (Crypt::ECB) } my $crypt = Crypt::ECB->new(-key => $key); # cipher loadable? eval { $crypt->cipher('Unknown') }; ok($@ =~ /^Couldn't load/, 'cipher: module could not be loaded'); # check cipher is set eval { $crypt->start('decryption') }; ok($@ =~ /^Can't start/, 'start: cipher not set'); foreach my $cipher (@ciphers) { eval { $crypt->cipher($cipher) }; SKIP: { skip "$cipher not installed", 11 if $@; $crypt = Crypt::ECB->new(-cipher => $cipher); # custom padding works as expected? eval { $crypt->padding(sub {}) }; ok($@ =~ /^Provided/, "custom padding not sensible ($cipher)"); # check start is called before crypt eval { $crypt->crypt }; ok($@ =~ /^You tried/, "crypt: start not called ($cipher)"); # check start is called before finish eval { $crypt->finish }; ok($@ =~ /^You tried/, "finish: start not called ($cipher)"); # check mode is [^de] eval { $crypt->start('nonsense') }; ok($@ =~ /^Mode has/, "start: mode not recognized ($cipher)"); # check key is set eval { $crypt->start('decryption') }; ok($@ =~ /^Key not set/, "start: key not set ($cipher)"); # check start w/o finish before $crypt->key( substr($key, 0, $crypt->keysize || 56) ); $crypt->start('encryption'); $crypt->crypt($plaintext); eval { $crypt->start('decryption') }; ok($@ =~ /^Not yet/, "start: finish not called ($cipher)"); $crypt->finish; # check padding is set when data % $bs $crypt->padding('none'); eval { $crypt->encrypt($plaintext) }; ok($@ =~ /^Your message/, "_pad: no padding and no full block ($cipher)"); # check padding is known $crypt->padding('unknown'); eval { $crypt->encrypt($plaintext) }; ok($@ =~ /^Padding/, "_pad: padding not defined ($cipher)"); # same for truncating $crypt->padding('unknown'); eval { $crypt->decrypt_hex( $ciphertext{$cipher} ) }; ok($@ =~ /^Padding/, "_truncate: padding not defined ($cipher)"); # check inconsistent standard padding is detected $crypt->padding('space'); my $enc = $crypt->encrypt($plaintext); $crypt->padding('standard'); eval { $crypt->decrypt($enc) }; ok($@ =~ /^Asked to/, "_truncate: inconsistent standard padding ($cipher)"); # check inconsistent zeroes padding is detected $crypt->padding('zeroes'); eval { $crypt->decrypt_hex( $ciphertext{$cipher} ) }; ok($@ =~ /^Block doesn't/, "_truncate: inconsistent zeroes padding ($cipher)"); } } Crypt-ECB-2.21/t/20-encryption.t0000644€€Fü€€0000000066512670215542020402 0ustar SL-SI+cappelSL-SI+Domain Users#!/usr/bin/perl -w use lib 't'; use Testdata; use Test::More tests => @ciphers + 1; BEGIN { use_ok (Crypt::ECB) } my $ecb = Crypt::ECB->new; foreach my $cipher (@ciphers) { eval { $ecb->cipher($cipher) }; SKIP: { skip "$cipher not installed", 1 if $@; my $ks = $ecb->keysize || 56; $ecb->key( substr($key, 0, $ks) ); my $enc = $ecb->encrypt_hex($plaintext); ok($enc eq $ciphertext{$cipher}, "$cipher: encryption"); } } Crypt-ECB-2.21/t/25-decryption.t0000644€€Fü€€0000000073612676735330020404 0ustar SL-SI+cappelSL-SI+Domain Users#!/usr/bin/perl -w use lib 't'; use Testdata; use Test::More tests => @ciphers + 1; BEGIN { use_ok (Crypt::ECB) } my $ecb = Crypt::ECB->new(-padding => 'none'); foreach my $cipher (@ciphers) { eval { $ecb->cipher($cipher) }; SKIP: { skip "$cipher not installed", 1 if $@; my $ks = $ecb->keysize || 56; $ecb->key( substr($key, 0, $ks) ); my $dec = $ecb->decrypt_hex($ciphertext{$cipher}); ok($dec eq $plaintext.$padding{'standard'}, "$cipher: decryption"); } } Crypt-ECB-2.21/t/30-start-crypt-finish.t0000644€€Fü€€0000000134412674724156021770 0ustar SL-SI+cappelSL-SI+Domain Users#!/usr/bin/perl -w use lib 't'; use Testdata; use Test::More tests => 2*@ciphers + 1; BEGIN { use_ok (Crypt::ECB) } my $ecb = Crypt::ECB->new; foreach my $cipher (@ciphers) { eval { $ecb->cipher($cipher) }; SKIP: { skip "$cipher not installed", 2 if $@; my $ks = $ecb->keysize || 56; $ecb->key( substr($key, 0, $ks) ); my ($enc, $dec); $ecb->start('encryption'); $enc .= $ecb->crypt foreach split(//, $plaintext); $enc .= $ecb->finish; ok(unpack('H*', $enc) eq $ciphertext{$cipher}, "$cipher: encryption using start/crypt/finish"); $ecb->start('decryption'); $dec .= $ecb->crypt($1) while $enc =~ /(.)/gs; $dec .= $ecb->finish; ok($dec eq $plaintext, "$cipher: decryption using start/crypt/finish"); } } Crypt-ECB-2.21/t/35-keychange.t0000644€€Fü€€0000000117312676735035020161 0ustar SL-SI+cappelSL-SI+Domain Users#!/usr/bin/perl -w use lib 't'; use Testdata; use Test::More tests => @ciphers-1 + 1; BEGIN { use_ok (Crypt::ECB) } my $ecb = Crypt::ECB->new; foreach my $cipher (grep {$_ ne 'NULL'} @ciphers) # NULL cipher doesn't work for this test { eval { $ecb->cipher($cipher) }; SKIP: { skip "$cipher not installed", 1 if $@; my $ks = $ecb->keysize || 56; $ecb->key( substr($key, 0, $ks) ); $ecb->padding('standard'); my $enc = $ecb->encrypt($plaintext); $ecb->key( substr(reverse($key), 0, $ks) ); $ecb->padding('none'); ok($ecb->decrypt($enc) ne $plaintext.$padding{'standard'}, "key change recognized ($cipher)"); } } Crypt-ECB-2.21/t/40-padding.t0000644€€Fü€€0000000127712670215542017620 0ustar SL-SI+cappelSL-SI+Domain Users#!/usr/bin/perl -w use lib 't'; use Testdata; use Test::More tests => 2*@ciphers*@padstyles + 1; BEGIN { use_ok (Crypt::ECB) } my $ecb = Crypt::ECB->new; foreach my $cipher (@ciphers) { eval { $ecb->cipher($cipher) }; SKIP: { skip "$cipher not installed", 2*@padstyles if $@; my $ks = $ecb->keysize || 56; $ecb->key( substr($key, 0, $ks) ); foreach my $padstyle (@padstyles) { $ecb->padding($padstyle); my $enc = $ecb->encrypt($plaintext); ok($ecb->decrypt($enc) eq $plaintext, "$cipher, $padstyle padding: en- and decryption"); $ecb->padding('none'); ok($ecb->decrypt($enc) eq $plaintext . $padding{$padstyle}, "$cipher, $padstyle padding: padded bytes"); } } } Crypt-ECB-2.21/t/45-padding-custom.t0000644€€Fü€€0000000162112673030526021126 0ustar SL-SI+cappelSL-SI+Domain Users#!/usr/bin/perl -w use lib 't'; use Testdata; my %padding = ( 'custom' => "XX", ); my $custom = sub { my ($data, $bs, $mode) = @_; $data .= 'X' x ($bs - length($data) % $bs) if ($mode eq 'e'); $data =~ s/X+$//s if ($mode eq 'd'); return $data; }; use Test::More tests => 2*@ciphers*1 + 1; BEGIN { use_ok (Crypt::ECB) } my $ecb = Crypt::ECB->new; foreach my $cipher (@ciphers) { eval { $ecb->cipher($cipher) }; SKIP: { skip "$cipher not installed", 2*(keys %padding) if $@; my $ks = $ecb->keysize || 56; $ecb->key( substr($key, 0, $ks) ); foreach my $padstyle (keys %padding) { $ecb->padding($custom); my $enc = $ecb->encrypt($plaintext); ok($ecb->decrypt($enc) eq $plaintext, "$cipher, $padstyle padding: en- and decryption"); $ecb->padding('none'); ok($ecb->decrypt($enc) eq $plaintext . $padding{$padstyle}, "$cipher, $padstyle padding: padded bytes"); } } } Crypt-ECB-2.21/t/50-padding-fullblock.t0000644€€Fü€€0000000261512670215542021571 0ustar SL-SI+cappelSL-SI+Domain Users#!/usr/bin/perl -w use lib 't'; use Testdata; my @w_extra_block = qw(standard zeroes oneandzeroes null); my @wo_extra_block = qw(rijndael_compat space none); use Test::More tests => 2*@ciphers*(4+3) + 1; BEGIN { use_ok (Crypt::ECB) } my $ecb = Crypt::ECB->new; foreach my $cipher (@ciphers) { eval { $ecb->cipher($cipher) }; SKIP: { skip "$cipher not installed", 2 * (@w_extra_block + @wo_extra_block) if $@; my $ks = $ecb->keysize || 56; $ecb->key( substr($key, 0, $ks) ); my $bs = $ecb->blocksize; my $text = "x" x $bs; my %padding = ( 'standard' => chr($bs) x $bs, 'zeroes' => "\x00" x ($bs-1) . chr($bs), 'oneandzeroes' => "\x80" . "\x00" x ($bs-1), 'null' => "\x00" x $bs, ); foreach my $padstyle (@w_extra_block) { $ecb->padding($padstyle); my $enc = $ecb->encrypt($text); ok($ecb->decrypt($enc) eq $text, "$cipher, $padstyle padding: en-/decrypting one block ($bs bytes)"); $ecb->padding('none'); ok($ecb->decrypt($enc) eq $text . $padding{$padstyle}, "$cipher, $padstyle padding: extra block added"); } foreach my $padstyle (@wo_extra_block) { $ecb->padding($padstyle); my $enc = $ecb->encrypt($text); ok($ecb->decrypt($enc) eq $text, "$cipher, $padstyle padding: en-/decrypting one block ($bs bytes)"); $ecb->padding('none'); ok($ecb->decrypt($enc) eq $text, "$cipher, $padstyle padding: no extra block added"); } } } Crypt-ECB-2.21/t/60-substrings+nulls.t0000644€€Fü€€0000000251112760047457021550 0ustar SL-SI+cappelSL-SI+Domain Users#!/usr/bin/perl -w use lib 't'; use Testdata; use Test::More tests => 3*@ciphers*(@padstyles-1)*(length($plaintext)+1) + 1; BEGIN { use_ok (Crypt::ECB) } my $ecb = Crypt::ECB->new; $plaintext =~ s/ /_/g; # spaces clash with 'space' padding @padstyles = grep {$_ ne 'null'} @padstyles; # testing "\0" clashes with 'null' padding foreach my $cipher (@ciphers) { eval { $ecb->cipher($cipher) }; SKIP: { skip "$cipher not installed", 3*@padstyles*(length($plaintext)+1) if $@; my $ks = $ecb->keysize || 56; $ecb->key( substr($key, 0, $ks) ); foreach my $padstyle (@padstyles) { $ecb->padding($padstyle); foreach my $len (0 .. length $plaintext) { my $plain = substr($plaintext, 0, $len); my $enc = $ecb->encrypt_hex($plain); my $dec = $ecb->decrypt_hex($enc); ok($dec eq $plain, "$cipher, $padstyle padding: en-/decrypting $len bytes plaintext"); $plain = substr($plaintext, 0, $len) . "0"; $enc = $ecb->encrypt_hex($plain); $dec = $ecb->decrypt_hex($enc); ok($dec eq $plain, "$cipher, $padstyle padding: en-/decrypting $len bytes plaintext plus '0'"); $plain = substr($plaintext, 0, $len) . "\0"; $enc = $ecb->encrypt_hex($plain); $dec = $ecb->decrypt_hex($enc); ok($dec eq $plain, "$cipher, $padstyle padding: en-/decrypting $len bytes plaintext plus '\\0'"); } } } } Crypt-ECB-2.21/t/80-preexisting.t0000644€€Fü€€0000000204412676735105020560 0ustar SL-SI+cappelSL-SI+Domain Users#!/usr/bin/perl -w use lib 't'; use Testdata; use Test::More tests => (@ciphers-1)*(@padstyles+5) + 1; BEGIN { use_ok (Crypt::ECB) } my $ecb = Crypt::ECB->new; foreach my $cipher (grep {$_ ne 'IDEA'} @ciphers) # IDEA doesn't work for this test { eval { $ecb->cipher($cipher) }; SKIP: { skip "$cipher not installed", @padstyles+5 if $@; my $cipher_mod = "Crypt::$cipher"; eval "require $cipher_mod"; my $xkey = substr($key, 0, $cipher_mod->keysize || 56); ok($ecb->cipher( $cipher_mod->new($xkey) ), "$cipher: loading pre-existing cipher object"); ok($ecb->module eq $cipher_mod, "$cipher: module matching"); ok($ecb->cipher eq $cipher, "$cipher: cipher matching"); ok($ecb->keysize == $cipher_mod->keysize, "$cipher: keysize matching"); ok($ecb->blocksize == $cipher_mod->blocksize, "$cipher: blocksize matching"); foreach my $padstyle (@padstyles) { $ecb->padding($padstyle); my $enc = $ecb->encrypt($plaintext); ok($ecb->decrypt($enc) eq $plaintext, "$cipher, $padstyle padding: en- and decryption"); } } } Crypt-ECB-2.21/t/85-preexisting-xtea.t0000644€€Fü€€0000000332112670216350021511 0ustar SL-SI+cappelSL-SI+Domain Users#!/usr/bin/perl -w use lib 't'; use Testdata; my $data = { '0' => { '16' => '333619a3ffdcef4e40c94d49d9ebdf7dcc0a0d6c97a5583e231b99230b04f03c', '32' => '6e2ca14be43fde47d5d456f8402b2a9c98984293b5cb4bb2b186113044098c03', '64' => 'd28b451d537cc731efab14a9b9f67f744e88804239d28b056bb455643378f808', }, '1' => { '16' => '98fc6c9fcc5a0426190a18e8e1dbb6e0e6017bda6cda03e7dda953127ccb7fab', '32' => '2746146a9a49a7ce15dc95aa5de110ac04107f1b83121754ce5836422c13e236', '64' => '42e0bc79a48f96c93b83bb8812f5ee6058c2846dfa3717e4bcf9e09df15cd4eb', }, }; use Test::More tests => 2*2*3 + 5; # 2 * #endiannesses * #rounds + 5 BEGIN { use_ok (Crypt::ECB) } my $cipher = 'XTEA'; my $cipher_mod = "Crypt::$cipher"; my $ecb = Crypt::ECB->new; eval { $ecb->cipher($cipher) }; SKIP: { skip "$cipher_mod not installed", (2 * keys(%{$data}) * keys( %{$data->{0}} ) + 4) if $@; eval "require $cipher_mod"; my $xkey = substr($key, 0, $cipher_mod->keysize); $ecb->cipher( $cipher_mod->new($xkey, 32, little_endian => 0) ); ok($ecb->module eq $cipher_mod, "$cipher: module"); ok($ecb->cipher eq $cipher, "$cipher: cipher"); ok($ecb->keysize == $cipher_mod->keysize, "$cipher: keysize"); ok($ecb->blocksize == $cipher_mod->blocksize, "$cipher: blocksize"); foreach my $endianness (sort keys %{$data}) { foreach my $rounds (sort keys %{$data->{$endianness}}) { $ecb->cipher( $cipher_mod->new($xkey, $rounds, little_endian => $endianness) ); my $enc = $ecb->encrypt_hex($plaintext); ok($enc eq $data->{$endianness}->{$rounds}, "$cipher, $rounds rounds, little endian $endianness: encryption"); ok($ecb->decrypt_hex($enc) eq $plaintext, "$cipher, $rounds rounds, little endian $endianness: decryption"); } } } Crypt-ECB-2.21/t/90-funcstyle.t0000644€€Fü€€0000000574012760047470020235 0ustar SL-SI+cappelSL-SI+Domain Users#!/usr/bin/perl -w use lib 't'; use Testdata; use Test::More tests => 3*4*@ciphers*(@padstyles-1)*(length($plaintext)+1) + 1; BEGIN { use_ok (Crypt::ECB, qw(encrypt decrypt encrypt_hex decrypt_hex)) } my $ecb = Crypt::ECB->new; $plaintext =~ s/ /_/g; # spaces clash with 'space' padding @padstyles = grep {$_ ne 'null'} @padstyles; # testing "\0" clashes with 'null' padding foreach my $cipher (@ciphers) { eval { $ecb->cipher($cipher) }; SKIP: { skip "$cipher not installed", 3*4*@padstyles*(length($plaintext)+1) if $@; my $ks = $ecb->keysize || 56; my $xkey = substr($key, 0, $ks); $ecb->key($xkey); foreach my $padstyle (@padstyles) { $ecb->padding($padstyle); foreach my $len (0 .. length $plaintext) { my $plain = substr($plaintext, 0, $len); my $enc1 = $ecb->encrypt($plain); my $enc2 = encrypt($xkey, $cipher, $plain, $padstyle); ok($enc1 eq $enc2, "$cipher, $padstyle padding, $len bytes: encryption function style"); my $dec = decrypt($xkey, $cipher, $enc2, $padstyle); ok($dec eq $plain, "$cipher, $padstyle padding, $len bytes: decryption function style"); $enc1 = $ecb->encrypt_hex($plain); $enc2 = encrypt_hex($xkey, $cipher, $plain, $padstyle); ok($enc1 eq $enc2, "$cipher, $padstyle padding, $len bytes: hex encryption function style"); $dec = decrypt_hex($xkey, $cipher, $enc2, $padstyle); ok($dec eq $plain, "$cipher, $padstyle padding, $len bytes: hex decryption function style"); $plain = substr($plaintext, 0, $len) . "0"; $enc1 = $ecb->encrypt($plain); $enc2 = encrypt($xkey, $cipher, $plain, $padstyle); ok($enc1 eq $enc2, "$cipher, $padstyle padding, $len bytes plus '0': encryption function style"); $dec = decrypt($xkey, $cipher, $enc2, $padstyle); ok($dec eq $plain, "$cipher, $padstyle padding, $len bytes plus '0': decryption function style"); $enc1 = $ecb->encrypt_hex($plain); $enc2 = encrypt_hex($xkey, $cipher, $plain, $padstyle); ok($enc1 eq $enc2, "$cipher, $padstyle padding, $len bytes plus '0': hex encryption function style"); $dec = decrypt_hex($xkey, $cipher, $enc2, $padstyle); ok($dec eq $plain, "$cipher, $padstyle padding, $len bytes plus '0': hex decryption function style"); $plain = substr($plaintext, 0, $len) . "\0"; $enc1 = $ecb->encrypt($plain); $enc2 = encrypt($xkey, $cipher, $plain, $padstyle); ok($enc1 eq $enc2, "$cipher, $padstyle padding, $len bytes plus '\\0': encryption function style"); $dec = decrypt($xkey, $cipher, $enc2, $padstyle); ok($dec eq $plain, "$cipher, $padstyle padding, $len bytes plus '\\0': decryption function style"); $enc1 = $ecb->encrypt_hex($plain); $enc2 = encrypt_hex($xkey, $cipher, $plain, $padstyle); ok($enc1 eq $enc2, "$cipher, $padstyle padding, $len bytes plus '\\0': hex encryption function style"); $dec = decrypt_hex($xkey, $cipher, $enc2, $padstyle); ok($dec eq $plain, "$cipher, $padstyle padding, $len bytes plus '\\0': hex decryption function style"); } } } } Crypt-ECB-2.21/t/Crypt/0000755€€Fü€€0000000000012771167757016716 5ustar SL-SI+cappelSL-SI+Domain UsersCrypt-ECB-2.21/t/Crypt/Dummy.pm0000644€€Fü€€0000000132612667532077020344 0ustar SL-SI+cappelSL-SI+Domain Userspackage Crypt::Dummy; use strict; use warnings; sub keysize { 16 } sub blocksize { 16 } sub new { my ($class, $key) = @_; my $len = length $key; my $ks = __PACKAGE__->keysize; die "Expected key of length $ks, got $len bytes ('$key')\n" unless $len == $ks; return bless \$key, $class; } sub encrypt { my ($key, $data) = @_; my $len = length $data; my $bs = __PACKAGE__->blocksize; die "Expected data of length $bs, got $len bytes ('$data')\n" unless $len == $bs; return $data ^ $$key; } sub decrypt { my ($key, $data) = @_; my $len = length $data; my $bs = __PACKAGE__->blocksize; die "Expected data of length $bs, got $len bytes ('$data')\n" unless $len == $bs; return $data ^ $$key; } 'END'; Crypt-ECB-2.21/t/Testdata.pm0000644€€Fü€€0000000565212771166337017725 0ustar SL-SI+cappelSL-SI+Domain Userspackage Testdata; use strict; use warnings; use vars qw(@ISA @EXPORT $key $plaintext %ciphertext @ciphers %padding @padstyles); require Exporter; @ISA = qw(Exporter); @EXPORT = qw($key $plaintext %ciphertext @ciphers %padding @padstyles); $key = "This is an at least 56 Byte long test key!!! It really is."; # binary would be better $plaintext = "This is just some dummy text!\n"; %ciphertext = ( 'Dummy' => '00000000000000000b1b53155453030831480d064d040a00150b5815552a6e67', 'Blowfish' => '52a037af4a2aea2d10cc09183b433f1a12c5ce734067d597da040861fed3ae61', 'Blowfish_PP' => '52a037af4a2aea2d10cc09183b433f1a12c5ce734067d597da040861fed3ae61', 'Camellia' => '37adb2c1ba5a6be79c7b886cdd432853bd6dfa6eac8a02cd8a85174ecd17ed12', 'Camellia_PP' => '37adb2c1ba5a6be79c7b886cdd432853bd6dfa6eac8a02cd8a85174ecd17ed12', 'CAST5' => '811a469a643c4f1e9c0236ab1a76682bb918a95c33c7663203fb163df0eb264f', 'CAST5_PP' => '811a469a643c4f1e9c0236ab1a76682bb918a95c33c7663203fb163df0eb264f', 'DES' => 'a47b1b2c90fb3b7a7367c1844d3d07e620b943fdc6728a05e5cf69afe49da6e8', 'DES_PP' => 'a47b1b2c90fb3b7a7367c1844d3d07e620b943fdc6728a05e5cf69afe49da6e8', 'DES_EDE3' => '9844c0d93c2d8cdf88203d169d2decc3d1d7212b6dfe747e3b10974657d96ec5', 'DES_EEE3' => '6bcbb21b218f84165a5c8b18627d4e68ed4d1475051a7c6ae74264e4ad49710f', 'IDEA' => '58678df1889afedbd336fe64a6fb39ab08156a201f832e9a8a2fd460251ebe24', 'NULL' => '54686973206973206a75737420736f6d652064756d6d792074657874210a0202', 'OpenSSL::AES' => 'a7acc570d3d8fc33e215e369fbc3d6552cfb2c2bf39b5064d5310c0d32eedeb2', # same as Rijndael 'OpenSSL::Blowfish' => '1d766228b195088dbf7c82cf444a5d251c9def80b291ff982ab91f6a2500cafe', # differing from Blowfish! 'RC6' => '9f1a68eec264ef9434e7585fede0c23f53d8e8ae2531b945682c924328d60632', 'Rijndael' => 'a7acc570d3d8fc33e215e369fbc3d6552cfb2c2bf39b5064d5310c0d32eedeb2', 'Rijndael_PP' => 'a7acc570d3d8fc33e215e369fbc3d6552cfb2c2bf39b5064d5310c0d32eedeb2', # Serpent taken out. The latest version is from 2002 and it is broken on many platforms. # 'Serpent' => '0f9516eb0e8ce6cb18768066921ec8456a184458620c1c9aaf338929fec46686', 'Skip32' => '121fe77e2e75e083d1ec5efc3e028f792982ddc07f44e1978faa58cb56ec8497', 'Twofish' => '4873e7735f4c976b4ba9f041d5fc82dea713d312959ad1a710225f0cbc8cf706', # Twofish2 taken out. In older versions there is a serious bug in the implementation, # so on environments using such versions, this test might report an error. # 'Twofish2' => '0958c674179aefaf13de8b25a613174dc40a90b80918bce55d314c86ecd3db45', 'XTEA' => '6e2ca14be43fde47d5d456f8402b2a9c98984293b5cb4bb2b186113044098c03', 'XTEA_PP' => '6e2ca14be43fde47d5d456f8402b2a9c98984293b5cb4bb2b186113044098c03', ); @ciphers = sort keys %ciphertext; %padding = ( 'standard' => "\x02\x02", 'zeroes' => "\x00\x02", 'oneandzeroes' => "\x80\x00", 'rijndael_compat' => "\x80\x00", 'space' => "\x20\x20", 'null' => "\x00\x00", ); @padstyles = sort keys %padding; 'END';