line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
##################################################################################################
|
2
|
|
|
|
|
|
|
# This is an unofficial port of Chris Veness' AES implementation #
|
3
|
|
|
|
|
|
|
# (c) Chris Veness 2005-2011. Right of free use is #
|
4
|
|
|
|
|
|
|
# granted for all commercial or non-commercial use under CC-BY 3.0 licence. No warranty of #
|
5
|
|
|
|
|
|
|
# any form is offered. More info at http://www.movable-type.co.uk/scripts/aes.html #
|
6
|
|
|
|
|
|
|
##################################################################################################
|
7
|
|
|
|
|
|
|
package Crypt::AES::CTR;
|
8
|
|
|
|
|
|
|
|
9
|
2
|
|
|
2
|
|
20856
|
use 5.006;
|
|
2
|
|
|
|
|
7
|
|
|
2
|
|
|
|
|
85
|
|
10
|
2
|
|
|
2
|
|
19
|
use strict;
|
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
75
|
|
11
|
2
|
|
|
2
|
|
11
|
use warnings FATAL => 'all';
|
|
2
|
|
|
|
|
17
|
|
|
2
|
|
|
|
|
100
|
|
12
|
2
|
|
|
2
|
|
1892
|
use Encode;
|
|
2
|
|
|
|
|
170054
|
|
|
2
|
|
|
|
|
214
|
|
13
|
2
|
|
|
2
|
|
2019
|
use POSIX;
|
|
2
|
|
|
|
|
16033
|
|
|
2
|
|
|
|
|
20
|
|
14
|
2
|
|
|
2
|
|
11571
|
use MIME::Base64;
|
|
2
|
|
|
|
|
1665
|
|
|
2
|
|
|
|
|
141
|
|
15
|
2
|
|
|
2
|
|
1801
|
use Time::HiRes;
|
|
2
|
|
|
|
|
4131
|
|
|
2
|
|
|
|
|
12
|
|
16
|
2
|
|
|
2
|
|
3526
|
use Math::BigInt;
|
|
2
|
|
|
|
|
54684
|
|
|
2
|
|
|
|
|
16
|
|
17
|
|
|
|
|
|
|
|
18
|
2
|
|
|
2
|
|
34688
|
use vars qw(@ISA @EXPORT_OK $VERSION $sBox $rCon $padding);
|
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
5723
|
|
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
require Exporter;
|
21
|
|
|
|
|
|
|
@ISA = qw(Exporter);
|
22
|
|
|
|
|
|
|
@EXPORT_OK = qw(encrypt decrypt);
|
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
=head1 NAME
|
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
Crypt::AES::CTR - This is a port of Chris Veness' AES implementation.
|
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
=head1 VERSION
|
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
Version 0.03
|
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
=cut
|
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
$VERSION = '0.03';
|
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
$padding="\n";
|
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
# sBox is pre-computed multiplicative inverse in GF(2^8) used in subBytes and keyExpansion [§5.1.1]
|
40
|
|
|
|
|
|
|
$sBox=[
|
41
|
|
|
|
|
|
|
0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,
|
42
|
|
|
|
|
|
|
0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,
|
43
|
|
|
|
|
|
|
0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,
|
44
|
|
|
|
|
|
|
0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,
|
45
|
|
|
|
|
|
|
0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,
|
46
|
|
|
|
|
|
|
0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,
|
47
|
|
|
|
|
|
|
0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,
|
48
|
|
|
|
|
|
|
0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,
|
49
|
|
|
|
|
|
|
0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,
|
50
|
|
|
|
|
|
|
0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,
|
51
|
|
|
|
|
|
|
0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,
|
52
|
|
|
|
|
|
|
0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,
|
53
|
|
|
|
|
|
|
0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,
|
54
|
|
|
|
|
|
|
0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,
|
55
|
|
|
|
|
|
|
0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,
|
56
|
|
|
|
|
|
|
0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16
|
57
|
|
|
|
|
|
|
];
|
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
# rCon is Round Constant used for the Key Expansion [1st col is 2^(r-1) in GF(2^8)] [§5.2]
|
60
|
|
|
|
|
|
|
$rCon=[
|
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
[(0x00, 0x00, 0x00, 0x00)],
|
63
|
|
|
|
|
|
|
[(0x01, 0x00, 0x00, 0x00)],
|
64
|
|
|
|
|
|
|
[(0x02, 0x00, 0x00, 0x00)],
|
65
|
|
|
|
|
|
|
[(0x04, 0x00, 0x00, 0x00)],
|
66
|
|
|
|
|
|
|
[(0x08, 0x00, 0x00, 0x00)],
|
67
|
|
|
|
|
|
|
[(0x10, 0x00, 0x00, 0x00)],
|
68
|
|
|
|
|
|
|
[(0x20, 0x00, 0x00, 0x00)],
|
69
|
|
|
|
|
|
|
[(0x40, 0x00, 0x00, 0x00)],
|
70
|
|
|
|
|
|
|
[(0x80, 0x00, 0x00, 0x00)],
|
71
|
|
|
|
|
|
|
[(0x1b, 0x00, 0x00, 0x00)],
|
72
|
|
|
|
|
|
|
[(0x36, 0x00, 0x00, 0x00)]
|
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
];
|
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
=head1 SYNOPSIS
|
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
This module encrypts and decrypts AES strings using CTR and Chris Veness' AES implementation. It is compatible with PHP encrypting and decrypting.
|
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
use Crypt::AES::CTR;
|
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
my $plaintext 'string';
|
86
|
|
|
|
|
|
|
my $ciphertext = Crypt::AES::CTR::encrypt($plaintext,'password',256);
|
87
|
|
|
|
|
|
|
$plaintext = Crypt::AES::CTR::decrypt($ciphertext,'password',256);
|
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
=head1 SUBROUTINES/METHODS
|
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
=head2 encrypt($plaintext, $key, $nbits)
|
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
Encrypt a text using AES encryption in Counter mode of operation
|
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
Unicode multi-byte character safe
|
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
$plaintext - plaintext Source text to be encrypted
|
99
|
|
|
|
|
|
|
$key - The password to use to generate a key
|
100
|
|
|
|
|
|
|
$nbits - Number of bits to be used in the key (128, 192, or 256)
|
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
returns encrypted text string
|
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
=cut
|
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
sub encrypt {
|
108
|
2
|
|
|
2
|
1
|
820
|
my ($self,$plaintext,$password,$nBits,$keySchedule,$pad);
|
109
|
|
|
|
|
|
|
|
110
|
2
|
100
|
|
|
|
9
|
if (ref($_[0]) eq 'Crypt::AES::CTR') { #check for oo
|
111
|
1
|
|
|
|
|
2
|
$self=shift;
|
112
|
1
|
|
|
|
|
3
|
$plaintext=shift;
|
113
|
1
|
|
33
|
|
|
6
|
$password=shift||$self->{password};
|
114
|
1
|
|
33
|
|
|
6
|
$nBits=shift||$self->{nbits};
|
115
|
1
|
50
|
33
|
|
|
9
|
$keySchedule=$self->{keyschedule} if ($password eq $self->{password} and $nBits eq $self->{nbits});
|
116
|
1
|
|
|
|
|
2
|
$pad=$self->{padding};
|
117
|
|
|
|
|
|
|
} else {
|
118
|
1
|
|
|
|
|
2
|
$plaintext=shift;
|
119
|
1
|
|
|
|
|
2
|
$password=shift;
|
120
|
1
|
|
50
|
|
|
5
|
$nBits=shift||0;
|
121
|
1
|
|
|
|
|
2
|
$pad=$padding;
|
122
|
|
|
|
|
|
|
}
|
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
|
125
|
2
|
|
|
|
|
4
|
my $blockSize = 16; # block size fixed at 16 bytes / 128 bits (Nb=4) for AES
|
126
|
2
|
50
|
33
|
|
|
20
|
if (!($nBits==128 or $nBits==192 or $nBits==256)) { return ''; } # standard allows 128/192/256 bit keys
|
|
0
|
|
33
|
|
|
0
|
|
127
|
2
|
|
|
|
|
11
|
$plaintext = Encode::encode_utf8($plaintext);
|
128
|
2
|
100
|
|
|
|
17
|
$keySchedule=_key($password,$nBits) if !defined($keySchedule);
|
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
# initialise 1st 8 bytes of counter block with nonce (NIST SP800-38A §B.2): [0-1] = millisec,
|
131
|
|
|
|
|
|
|
# [2-3] = random, [4-7] = seconds, together giving full sub-millisec uniqueness up to Feb 2106
|
132
|
2
|
|
|
|
|
10
|
my @counterBlock = (('') x $blockSize);
|
133
|
|
|
|
|
|
|
|
134
|
2
|
|
|
|
|
47
|
my $nonce = sprintf('%.3f',Time::HiRes::time());
|
135
|
2
|
|
|
|
|
9
|
my ($nonceSec,$nonceMs) = split/\./, $nonce;
|
136
|
2
|
|
|
|
|
67
|
my $nonceRnd = floor(rand(0.99999999)*0xffff);
|
137
|
|
|
|
|
|
|
|
138
|
2
|
|
|
|
|
8
|
for (my $i=0; $i<2; $i++) { $counterBlock[$i] = _urs($nonceMs , $i*8) & 0xff;}
|
|
4
|
|
|
|
|
11
|
|
139
|
2
|
|
|
|
|
8
|
for (my $i=0; $i<2; $i++) { $counterBlock[$i+2] = _urs($nonceRnd , $i*8) & 0xff;}
|
|
4
|
|
|
|
|
9
|
|
140
|
2
|
|
|
|
|
6
|
for (my $i=0; $i<4; $i++) { $counterBlock[$i+4] = _urs($nonceSec , $i*8) & 0xff;}
|
|
8
|
|
|
|
|
15
|
|
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
# and convert it to a string to go on the front of the ciphertext
|
143
|
2
|
|
|
|
|
4
|
my $ctrTxt = '';
|
144
|
2
|
|
|
|
|
7
|
for (my $i=0; $i<8; $i++) { $ctrTxt .= chr($counterBlock[$i]); }
|
|
16
|
|
|
|
|
39
|
|
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
# generate key schedule - an expansion of the key into distinct Key Rounds for each round
|
147
|
2
|
|
|
|
|
17
|
my $blockCount = ceil(length($plaintext)/$blockSize);
|
148
|
2
|
|
|
|
|
5
|
my @ciphertxt = ('') x $blockCount; # ciphertext as array of strings
|
149
|
|
|
|
|
|
|
|
150
|
2
|
|
|
|
|
7
|
for (my $b=0; $b<$blockCount; $b++) {
|
151
|
|
|
|
|
|
|
# set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)
|
152
|
|
|
|
|
|
|
# done in two stages for 32-bit ops: using two words allows us to go past 2^32 blocks (68GB)
|
153
|
2
|
|
|
|
|
8
|
for (my $c=0; $c<4; $c++) { $counterBlock[15-$c] = _urs($b , $c*8) & 0xff; }
|
|
8
|
|
|
|
|
16
|
|
154
|
2
|
|
|
|
|
7
|
for (my $c=0; $c<4; $c++) {
|
155
|
|
|
|
|
|
|
# $counterBlock[15-$c-4] = _urs($b/0x100000000 , $c*8);
|
156
|
8
|
|
|
|
|
37
|
my $x = Math::BigInt->new($b);
|
157
|
8
|
|
|
|
|
823
|
$x->bdiv('0x100000000');
|
158
|
8
|
|
|
|
|
2093
|
$counterBlock[15-$c-4] = _urs($x , $c*8);
|
159
|
|
|
|
|
|
|
}
|
160
|
2
|
|
|
|
|
7
|
my $cipherCntr = _cipher(\@counterBlock, $keySchedule,0); # -- encrypt counter block --
|
161
|
|
|
|
|
|
|
# block size is reduced on final block
|
162
|
2
|
50
|
|
|
|
11
|
my $blockLength = $b<$blockCount-1 ? $blockSize : (length($plaintext)-1)%$blockSize+1;
|
163
|
2
|
|
|
|
|
8
|
my @cipherChar = (('') x $blockLength);
|
164
|
|
|
|
|
|
|
|
165
|
2
|
|
|
|
|
7
|
for (my $i=0; $i<$blockLength; $i++) { # -- xor plaintext with ciphered counter char-by-char --
|
166
|
22
|
|
|
|
|
44
|
$cipherChar[$i] = $cipherCntr->[$i] ^ ord(substr($plaintext, $b*$blockSize+$i, 1));
|
167
|
22
|
|
|
|
|
72
|
$cipherChar[$i] = chr($cipherChar[$i]);
|
168
|
|
|
|
|
|
|
}
|
169
|
2
|
|
|
|
|
18
|
$ciphertxt[$b] = join('',@cipherChar);
|
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
}
|
172
|
2
|
|
|
|
|
7
|
my $ciphertext = $ctrTxt . join('',@ciphertxt);
|
173
|
2
|
|
|
|
|
1052
|
$ciphertext = MIME::Base64::encode_base64($ciphertext,$pad); #// encode in base64
|
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
|
176
|
2
|
|
|
|
|
80
|
return $ciphertext;
|
177
|
|
|
|
|
|
|
}
|
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
=head2 decrypt($ciphertext, $key, $nbits)
|
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
Decrypt a text encrypted by AES in counter mode of operation
|
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
$ciphertext - Source text to be decrypted
|
185
|
|
|
|
|
|
|
$key - The password to use to generate a key
|
186
|
|
|
|
|
|
|
$nbits - Number of bits to be used in the key (128, 192, or 256)
|
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
returns decrypted text
|
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
=cut
|
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
sub decrypt {
|
193
|
2
|
|
|
2
|
1
|
4521
|
my ($self,$ciphertext,$password,$nBits,$keySchedule);
|
194
|
|
|
|
|
|
|
|
195
|
2
|
100
|
|
|
|
12
|
if (ref($_[0]) eq 'Crypt::AES::CTR') { #check for oo
|
196
|
1
|
|
|
|
|
2
|
$self=shift;
|
197
|
1
|
|
|
|
|
2
|
$ciphertext=shift;
|
198
|
1
|
|
33
|
|
|
7
|
$password=shift||$self->{password};
|
199
|
1
|
|
33
|
|
|
6
|
$nBits=shift||$self->{nbits};
|
200
|
1
|
50
|
33
|
|
|
11
|
$keySchedule=$self->{keyschedule} if ($password eq $self->{password} and $nBits eq $self->{nbits});
|
201
|
|
|
|
|
|
|
} else {
|
202
|
1
|
|
|
|
|
2
|
$ciphertext=shift;
|
203
|
1
|
|
|
|
|
2
|
$password=shift;
|
204
|
1
|
|
50
|
|
|
6
|
$nBits=shift||0;
|
205
|
|
|
|
|
|
|
}
|
206
|
|
|
|
|
|
|
|
207
|
2
|
|
|
|
|
4
|
my $blockSize = 16; # block size fixed at 16 bytes / 128 bits (Nb=4) for AES
|
208
|
2
|
50
|
33
|
|
|
21
|
if (!($nBits==128 || $nBits==192 || $nBits==256)){
|
|
|
|
33
|
|
|
|
|
209
|
0
|
|
|
|
|
0
|
return ''; # standard allows 128/192/256 bit keys
|
210
|
|
|
|
|
|
|
}
|
211
|
2
|
|
|
|
|
10
|
$ciphertext = MIME::Base64::decode_base64($ciphertext);
|
212
|
2
|
100
|
|
|
|
8
|
$keySchedule=_key($password,$nBits) if !defined($keySchedule);
|
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
# recover nonce from 1st element of ciphertext
|
215
|
2
|
|
|
|
|
5
|
my @counterBlock = ();#array
|
216
|
2
|
|
|
|
|
5
|
my $ctrTxt = substr($ciphertext, 0, 8);
|
217
|
2
|
|
|
|
|
6
|
for (my $i=0; $i<8; $i++){
|
218
|
16
|
|
|
|
|
33
|
$counterBlock[$i] = ord(substr($ctrTxt,$i,1));
|
219
|
|
|
|
|
|
|
}
|
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
# separate ciphertext into blocks (skipping past initial 8 bytes)
|
223
|
2
|
|
|
|
|
9
|
my $nBlocks = ceil((length($ciphertext)-8) / $blockSize);
|
224
|
2
|
|
|
|
|
7
|
my @ct = ('') x $nBlocks;#array
|
225
|
2
|
|
|
|
|
5
|
for ($b=0; $b<$nBlocks; $b++){
|
226
|
2
|
|
|
|
|
9
|
$ct[$b] = substr($ciphertext, 8+$b*$blockSize, 16);
|
227
|
|
|
|
|
|
|
}
|
228
|
2
|
|
|
|
|
3
|
my @ciphertext = @ct; # ciphertext is now array of block-length strings
|
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
# plaintext will get generated block-by-block into array of block-length strings
|
231
|
2
|
|
|
|
|
4
|
my @plaintxt = ('') x $#ciphertext;#array
|
232
|
|
|
|
|
|
|
|
233
|
2
|
|
|
|
|
7
|
for (my $b=0; $b<$nBlocks; $b++) {
|
234
|
|
|
|
|
|
|
# set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)
|
235
|
2
|
|
|
|
|
17
|
for (my $c=0; $c<4; $c++){
|
236
|
8
|
|
|
|
|
16
|
$counterBlock[15-$c] = _urs($b, $c*8) & 0xff;
|
237
|
|
|
|
|
|
|
}
|
238
|
2
|
|
|
|
|
12
|
for (my $c=0; $c<4; $c++){
|
239
|
|
|
|
|
|
|
#$counterBlock[15-$c-4] = _urs(($b+1)/0x100000000-1, $c*8) & 0xff;
|
240
|
8
|
|
|
|
|
807
|
my $x = Math::BigInt->new(($b+1));
|
241
|
8
|
|
|
|
|
241
|
$x->bdiv('0x100000000');
|
242
|
8
|
|
|
|
|
1885
|
$counterBlock[15-$c-4] = _urs($x, $c*8) & 0xff;
|
243
|
|
|
|
|
|
|
}
|
244
|
2
|
|
|
|
|
258
|
my $cipherCntr = _cipher(\@counterBlock, $keySchedule); # encrypt counter block
|
245
|
2
|
|
|
|
|
8
|
my @plaintxtByte = ('') x length($ciphertext[$b]);#array
|
246
|
2
|
|
|
|
|
7
|
for (my $i=0; $i
|
247
|
|
|
|
|
|
|
# -- xor plaintext with ciphered counter byte-by-byte --
|
248
|
22
|
|
|
|
|
33
|
$plaintxtByte[$i] = $cipherCntr->[$i] ^ ord(substr($ciphertext[$b],$i,1));
|
249
|
22
|
|
|
|
|
49
|
$plaintxtByte[$i] = chr($plaintxtByte[$i]);
|
250
|
|
|
|
|
|
|
}
|
251
|
2
|
|
|
|
|
16
|
$plaintxt[$b] = join('', @plaintxtByte); #php implode
|
252
|
|
|
|
|
|
|
}
|
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
# join array of blocks into single plaintext string
|
255
|
2
|
|
|
|
|
6
|
my $plaintext = join('',@plaintxt);
|
256
|
2
|
|
|
|
|
13
|
$plaintext = Encode::decode_utf8($plaintext); #decode from UTF8 back to Unicode multi-byte chars
|
257
|
2
|
|
|
|
|
134
|
return $plaintext;
|
258
|
|
|
|
|
|
|
}
|
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
=head2 aes_padding($padding)
|
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
Override default padding(\n) for base64 encodes
|
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
=cut
|
265
|
|
|
|
|
|
|
|
266
|
0
|
|
|
0
|
1
|
0
|
sub aes_padding { $padding=shift; }
|
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
=head1 OO-INTERFACE
|
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
=head2 new
|
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
my $crypt = Crypt::AES::CTR->new( key=>$key, nbits=>$nbits , padding => $padding );
|
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
#Unicode multi-byte character safe
|
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
#$key - The password to use to generate a key
|
277
|
|
|
|
|
|
|
#$nbits - Number of bits to be used in the key (128, 192, or 256)
|
278
|
|
|
|
|
|
|
#$padding - What to use as padding for base64 encodes, default is \n (optional)
|
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
#returns blessed reference
|
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
$crypt->encrypt($plaintext); # use cached $key and $nbits from new declaration
|
283
|
|
|
|
|
|
|
$crypt->encrypt($plaintext, $key, $nbits); #override $key and $nbits
|
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
# see documentation above for encrypt function
|
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
$crypt->decrypt($plaintext); # use cached $key and $nbits from new declaration
|
288
|
|
|
|
|
|
|
$crypt->decrypt($plaintext, $key, $nbits); #override $key and $nbits
|
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
# see documentation above for decrypt function
|
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
=cut
|
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
# 00-style interface
|
295
|
|
|
|
|
|
|
sub new {
|
296
|
1
|
|
|
1
|
1
|
849
|
my $class = shift;
|
297
|
1
|
|
|
|
|
2
|
my $self = {};
|
298
|
1
|
|
|
|
|
5
|
my %new = @_;
|
299
|
1
|
|
50
|
|
|
7
|
bless($self, ($class||'Crypt::AES::CTR') );
|
300
|
1
|
|
|
|
|
10
|
$self->{password}=$new{key};
|
301
|
1
|
|
50
|
|
|
6
|
$self->{nbits}=$new{nbits}||0;
|
302
|
1
|
50
|
33
|
|
|
21
|
if (!($self->{nbits}==128 || $self->{nbits}==192 || $self->{nbits}==256)){
|
|
|
|
33
|
|
|
|
|
303
|
0
|
|
|
|
|
0
|
return ''; # standard allows 128/192/256 bit keys
|
304
|
|
|
|
|
|
|
}
|
305
|
1
|
|
33
|
|
|
6
|
$self->{padding}=$new{padding}||$padding;
|
306
|
1
|
|
|
|
|
5
|
$self->{keyschedule}=_key($self->{password},$self->{nbits});
|
307
|
1
|
|
|
|
|
7
|
return $self;
|
308
|
|
|
|
|
|
|
}
|
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
# Unsigned right shift function, since Perl has neither >>> operator nor unsigned ints
|
311
|
|
|
|
|
|
|
#
|
312
|
|
|
|
|
|
|
# @param a number to be shifted (32-bit integer)
|
313
|
|
|
|
|
|
|
# @param b number of bits to shift a to the right (0..31)
|
314
|
|
|
|
|
|
|
# @return a right-shifted and zero-filled by b bits
|
315
|
|
|
|
|
|
|
#
|
316
|
|
|
|
|
|
|
sub _urs {
|
317
|
48
|
|
|
48
|
|
67
|
my($xa, $b) = @_;
|
318
|
48
|
|
|
|
|
83
|
$xa &= 0xffffffff; $b &= 0x1f; # (bounds check)
|
|
48
|
|
|
|
|
2533
|
|
319
|
48
|
50
|
33
|
|
|
117
|
if ($xa&0x80000000 && $b>0) { # if left-most bit set
|
320
|
0
|
|
|
|
|
0
|
$xa = ($xa>>1) & 0x7fffffff; # right-shift one bit & clear left-most bit
|
321
|
0
|
|
|
|
|
0
|
$xa = $xa >> ($b-1); # remaining right-shifts
|
322
|
|
|
|
|
|
|
} else { # otherwise
|
323
|
48
|
|
|
|
|
3132
|
$xa = ($xa>>$b); # use normal right-shift
|
324
|
|
|
|
|
|
|
}
|
325
|
48
|
|
|
|
|
2333
|
return $xa;
|
326
|
|
|
|
|
|
|
}
|
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
# Handle key and keyschedule
|
329
|
|
|
|
|
|
|
sub _key {
|
330
|
3
|
|
|
3
|
|
6
|
my $password = shift;
|
331
|
3
|
|
|
|
|
4
|
my $nBits = shift;
|
332
|
3
|
|
|
|
|
13
|
$password = Encode::encode_utf8($password);
|
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
# use AES itself to encrypt password to get cipher key (using plain password as source for key
|
335
|
|
|
|
|
|
|
# expansion) - gives us well encrypted key (though hashed key might be preferred for prod'n use)
|
336
|
3
|
|
|
|
|
23
|
my $nBytes = $nBits/8; # no bytes in key (16/24/32)
|
337
|
3
|
|
|
|
|
18
|
my @pwBytes = ('') x $nBytes;
|
338
|
3
|
|
|
|
|
12
|
for (my $i=0; $i<$nBytes; $i++) { # use 1st 16/24/32 chars of password for key
|
339
|
96
|
100
|
|
|
|
259
|
$pwBytes[$i] = ($i>=length($password)) ? 0:ord(substr($password,$i,1));
|
340
|
|
|
|
|
|
|
}
|
341
|
|
|
|
|
|
|
|
342
|
3
|
|
|
|
|
12
|
my $key = _cipher(\@pwBytes, _keyExpansion(\@pwBytes)); # gives us 16-byte key
|
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
#$key = [ @{$key},splice($key,0, $nBytes-16) ]; # expand key to 16/24/32 bytes long
|
345
|
3
|
|
|
|
|
43
|
$key = [ @{$key}, map{ $key->[$_] } (0..($nBytes-16-1)) ]; # expand key to 16/24/32 bytes long
|
|
3
|
|
|
|
|
16
|
|
|
48
|
|
|
|
|
88
|
|
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
# generate key schedule - an expansion of the key into distinct Key Rounds for each round
|
348
|
3
|
|
|
|
|
15
|
my $keySchedule = _keyExpansion($key);
|
349
|
|
|
|
|
|
|
|
350
|
3
|
|
|
|
|
26
|
return $keySchedule;
|
351
|
|
|
|
|
|
|
}
|
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
# AES Cipher function: encrypt 'input' with Rijndael algorithm
|
354
|
|
|
|
|
|
|
#
|
355
|
|
|
|
|
|
|
# @param input message as byte-array (16 bytes)
|
356
|
|
|
|
|
|
|
# @param w key schedule as 2D byte-array (Nr+1 x Nb bytes) -
|
357
|
|
|
|
|
|
|
# generated from the cipher key by keyExpansion()
|
358
|
|
|
|
|
|
|
# @return ciphertext as byte-array (16 bytes)
|
359
|
|
|
|
|
|
|
#
|
360
|
|
|
|
|
|
|
sub _cipher { # main cipher function [§5.1]
|
361
|
7
|
|
|
7
|
|
13
|
my $input = shift;
|
362
|
7
|
|
|
|
|
10
|
my $w = shift;
|
363
|
|
|
|
|
|
|
|
364
|
7
|
|
|
|
|
8
|
my $Nb = 4; # block size (in words): no of columns in state (fixed at 4 for AES)
|
365
|
7
|
|
|
|
|
14
|
my $Nr = scalar(@{$w})/$Nb - 1; # no of rounds: 10/12/14 for 128/192/256-bit keys
|
|
7
|
|
|
|
|
20
|
|
366
|
|
|
|
|
|
|
|
367
|
7
|
|
|
|
|
18
|
my $state = [[],[],[],[]]; # initialise 4xNb byte-array 'state' with input [§3.4]
|
368
|
7
|
|
|
|
|
20
|
for(my $i=0; $i<4*$Nb; $i++){
|
369
|
112
|
|
|
|
|
448
|
$state->[$i%4][floor($i/4)] = $input->[$i];
|
370
|
|
|
|
|
|
|
}
|
371
|
|
|
|
|
|
|
|
372
|
7
|
|
|
|
|
15
|
$state = _addRoundKey($state, $w, 0, $Nb);
|
373
|
7
|
|
|
|
|
19
|
for(my $round=1; $round<$Nr; $round++) { # apply Nr rounds
|
374
|
91
|
|
|
|
|
144
|
$state = _subBytes($state, $Nb);
|
375
|
91
|
|
|
|
|
162
|
$state = _shiftRows($state, $Nb);
|
376
|
91
|
|
|
|
|
163
|
$state = _mixColumns($state, $Nb);
|
377
|
91
|
|
|
|
|
163
|
$state = _addRoundKey($state, $w, $round, $Nb);
|
378
|
|
|
|
|
|
|
}
|
379
|
7
|
|
|
|
|
13
|
$state = _subBytes($state, $Nb);
|
380
|
7
|
|
|
|
|
14
|
$state = _shiftRows($state, $Nb);
|
381
|
7
|
|
|
|
|
24
|
$state = _addRoundKey($state, $w, $Nr, $Nb);
|
382
|
7
|
|
|
|
|
60
|
my @output = ('') x (4*$Nb); # convert state to 1-d array before returning [§3.4]
|
383
|
7
|
|
|
|
|
23
|
for (my $i=0; $i<4*$Nb; $i++){
|
384
|
112
|
|
|
|
|
411
|
$output[$i] = $state->[$i%4][floor($i/4)];
|
385
|
|
|
|
|
|
|
}
|
386
|
|
|
|
|
|
|
|
387
|
7
|
|
|
|
|
36
|
return \@output;
|
388
|
|
|
|
|
|
|
}
|
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
# Key expansion for Rijndael cipher(): performs key expansion on cipher key
|
391
|
|
|
|
|
|
|
# to generate a key schedule
|
392
|
|
|
|
|
|
|
#
|
393
|
|
|
|
|
|
|
# @param key cipher key byte-array (16 bytes)
|
394
|
|
|
|
|
|
|
# @return key schedule as 2D byte-array (Nr+1 x Nb bytes)
|
395
|
|
|
|
|
|
|
#
|
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
sub _keyExpansion { # generate Key Schedule from Cipher Key [§5.2]
|
398
|
6
|
|
|
6
|
|
10
|
my $key = shift;
|
399
|
6
|
|
|
|
|
8
|
my $Nb = 4; # block size (in words): no of columns in state (fixed at 4 for AES)
|
400
|
6
|
|
|
|
|
8
|
my $Nk = scalar(@{$key})/4; # key length (in words): 4/6/8 for 128/192/256-bit keys
|
|
6
|
|
|
|
|
37
|
|
401
|
6
|
|
|
|
|
10
|
my $Nr = $Nk + 6; # no of rounds: 10/12/14 for 128/192/256-bit keys
|
402
|
|
|
|
|
|
|
|
403
|
6
|
|
|
|
|
63
|
my @w = ('') x ($Nb*($Nr+1));#array
|
404
|
6
|
|
|
|
|
19
|
for(my $i=0; $i<$Nb*($Nr+1); $i++){
|
405
|
360
|
|
|
|
|
770
|
$w[$i] = 0;
|
406
|
|
|
|
|
|
|
}
|
407
|
6
|
|
|
|
|
14
|
my @temp = ('0') x 4;#array
|
408
|
6
|
|
|
|
|
17
|
for(my $i=0; $i<$Nk; $i++) {
|
409
|
48
|
|
|
|
|
123
|
my $r = [$key->[4*$i], $key->[4*$i+1], $key->[4*$i+2], $key->[4*$i+3]];
|
410
|
48
|
|
|
|
|
119
|
$w[$i] = $r;
|
411
|
|
|
|
|
|
|
}
|
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
|
414
|
6
|
|
|
|
|
20
|
for (my $i=$Nk; $i<($Nb*($Nr+1)); $i++) {
|
415
|
312
|
|
|
|
|
706
|
$w[$i] = [(('0') x 4)];#array
|
416
|
|
|
|
|
|
|
|
417
|
312
|
|
|
|
|
610
|
for (my $t=0; $t<4; $t++){
|
418
|
1248
|
|
|
|
|
2549
|
$temp[$t] = $w[$i-1][$t];
|
419
|
|
|
|
|
|
|
}
|
420
|
312
|
100
|
66
|
|
|
1225
|
if($i % $Nk == 0){
|
|
|
100
|
|
|
|
|
|
421
|
42
|
|
|
|
|
78
|
my $temp1 = _rotWord(\@temp);
|
422
|
42
|
|
|
|
|
69
|
my $temp2 = _subWord($temp1);
|
423
|
42
|
|
|
|
|
91
|
@temp = @$temp2;
|
424
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
|
426
|
42
|
|
|
|
|
89
|
for (my $t=0; $t<4; $t++){
|
427
|
168
|
|
|
|
|
404
|
$temp[$t] ^= $rCon->[$i/$Nk][$t];
|
428
|
|
|
|
|
|
|
}
|
429
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
} elsif ($Nk > 6 and ($i % $Nk) == 4) {
|
431
|
|
|
|
|
|
|
|
432
|
36
|
|
|
|
|
55
|
my $temp2 = _subWord(\@temp);
|
433
|
36
|
|
|
|
|
95
|
@temp = @$temp2;
|
434
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
}
|
437
|
312
|
|
|
|
|
580
|
for (my $t=0; $t<4; $t++){
|
438
|
1248
|
|
|
|
|
3480
|
$w[$i][$t] = $w[$i-$Nk][$t] ^ $temp[$t];
|
439
|
|
|
|
|
|
|
}
|
440
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
}
|
442
|
|
|
|
|
|
|
|
443
|
6
|
|
|
|
|
20
|
return \@w;
|
444
|
|
|
|
|
|
|
}
|
445
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
# ---- remaining routines are private, not called externally ----
|
450
|
|
|
|
|
|
|
|
451
|
|
|
|
|
|
|
sub _subBytes { # apply SBox to state S [§5.1.1]
|
452
|
98
|
|
|
98
|
|
110
|
my $s = shift;
|
453
|
98
|
|
|
|
|
119
|
my $Nb = shift;
|
454
|
|
|
|
|
|
|
|
455
|
98
|
|
|
|
|
199
|
for (my $r=0; $r<4; $r++) {
|
456
|
392
|
|
|
|
|
868
|
for (my $c=0; $c<$Nb; $c++){
|
457
|
1568
|
|
|
|
|
7070
|
$s->[$r][$c] = $sBox->[$s->[$r][$c]];
|
458
|
|
|
|
|
|
|
}
|
459
|
|
|
|
|
|
|
}
|
460
|
98
|
|
|
|
|
169
|
return $s;
|
461
|
|
|
|
|
|
|
}
|
462
|
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
sub _shiftRows { # shift row r of state S left by r bytes [§5.1.2]
|
464
|
98
|
|
|
98
|
|
107
|
my $s = shift;
|
465
|
98
|
|
|
|
|
102
|
my $Nb = shift;
|
466
|
|
|
|
|
|
|
|
467
|
98
|
|
|
|
|
380
|
my @t = ('') x 4;#array
|
468
|
98
|
|
|
|
|
209
|
for (my $r=1; $r<4; $r++) {
|
469
|
294
|
|
|
|
|
522
|
for(my $c=0; $c<4; $c++){
|
470
|
1176
|
|
|
|
|
3161
|
$t[$c] = $s->[$r][($c+$r)%$Nb]; # shift into temp copy
|
471
|
|
|
|
|
|
|
}
|
472
|
294
|
|
|
|
|
709
|
for(my $c=0; $c<4; $c++){
|
473
|
1176
|
|
|
|
|
3305
|
$s->[$r][$c] = $t[$c]; # and copy back
|
474
|
|
|
|
|
|
|
}
|
475
|
|
|
|
|
|
|
}# note that this will work for Nb=4,5,6, but not 7,8 (always 4 for AES):
|
476
|
98
|
|
|
|
|
389
|
return $s; # see fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.311.pdf
|
477
|
|
|
|
|
|
|
}
|
478
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
sub _mixColumns { # combine bytes of each col of state S [§5.1.3]
|
480
|
91
|
|
|
91
|
|
105
|
my $s = shift;
|
481
|
91
|
|
|
|
|
103
|
my $Nb = shift;
|
482
|
|
|
|
|
|
|
|
483
|
91
|
|
|
|
|
184
|
for(my $c=0; $c<4; $c++) {
|
484
|
364
|
|
|
|
|
885
|
my @a = ('') x 4; # 'a' is a copy of the current column from 's'
|
485
|
364
|
|
|
|
|
806
|
my @b = ('') x 4; # 'b' is a•{02} in GF(2^8)
|
486
|
364
|
|
|
|
|
716
|
for(my $i=0; $i<4; $i++) {
|
487
|
1456
|
|
|
|
|
2333
|
$a[$i] = $s->[$i][$c];
|
488
|
1456
|
100
|
|
|
|
4945
|
$b[$i] = $s->[$i][$c]&0x80 ? $s->[$i][$c]<<1 ^ 0x011b : $s->[$i][$c]<<1;
|
489
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
}
|
491
|
|
|
|
|
|
|
# a[n] ^ b[n] is a•{03} in GF(2^8) #MYFIXED $xb
|
492
|
364
|
|
|
|
|
1215
|
$s->[0][$c] = $b[0] ^ $a[1] ^ $b[1] ^ $a[2] ^ $a[3]; # 2*a0 + 3*a1 + a2 + a3
|
493
|
364
|
|
|
|
|
565
|
$s->[1][$c] = $a[0] ^ $b[1] ^ $a[2] ^ $b[2] ^ $a[3]; # a0 * 2*a1 + 3*a2 + a3
|
494
|
364
|
|
|
|
|
497
|
$s->[2][$c] = $a[0] ^ $a[1] ^ $b[2] ^ $a[3] ^ $b[3]; # a0 + a1 + 2*a2 + 3*a3
|
495
|
364
|
|
|
|
|
1351
|
$s->[3][$c] = $a[0] ^ $b[0] ^ $a[1] ^ $a[2] ^ $b[3]; # 3*a0 + a1 + a2 + 2*a3
|
496
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
|
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
}
|
500
|
91
|
|
|
|
|
149
|
return $s;
|
501
|
|
|
|
|
|
|
}
|
502
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
sub _addRoundKey { # xor Round Key into state S [§5.1.4]
|
504
|
105
|
|
|
105
|
|
161
|
my($state, $w, $rnd, $Nb) = @_;
|
505
|
|
|
|
|
|
|
|
506
|
105
|
|
|
|
|
207
|
for (my $r=0; $r<4; $r++) {
|
507
|
420
|
|
|
|
|
756
|
for (my $c=0; $c<$Nb; $c++){
|
508
|
1680
|
|
|
|
|
6985
|
$state->[$r][$c] ^= $w->[$rnd*4+$c][$r];
|
509
|
|
|
|
|
|
|
}
|
510
|
|
|
|
|
|
|
}
|
511
|
|
|
|
|
|
|
|
512
|
105
|
|
|
|
|
303
|
return $state;
|
513
|
|
|
|
|
|
|
}
|
514
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
sub _subWord { # apply SBox to 4-byte word w
|
517
|
78
|
|
|
78
|
|
84
|
my $w = shift;
|
518
|
78
|
|
|
|
|
162
|
for(my $i=0; $i<4; $i++){
|
519
|
312
|
|
|
|
|
651
|
$w->[$i] = $sBox->[$w->[$i]];
|
520
|
|
|
|
|
|
|
}
|
521
|
78
|
|
|
|
|
111
|
return $w;
|
522
|
|
|
|
|
|
|
}
|
523
|
|
|
|
|
|
|
|
524
|
|
|
|
|
|
|
sub _rotWord { # rotate 4-byte word w left by one byte
|
525
|
42
|
|
|
42
|
|
51
|
my $w = shift;
|
526
|
|
|
|
|
|
|
|
527
|
42
|
|
|
|
|
55
|
my $tmp = $w->[0];
|
528
|
42
|
|
|
|
|
104
|
for(my $i=0; $i<3; $i++){
|
529
|
126
|
|
|
|
|
266
|
$w->[$i] = $w->[$i+1];
|
530
|
|
|
|
|
|
|
}
|
531
|
42
|
|
|
|
|
47
|
$w->[3] = $tmp;
|
532
|
42
|
|
|
|
|
72
|
return $w;
|
533
|
|
|
|
|
|
|
}
|
534
|
|
|
|
|
|
|
|
535
|
|
|
|
|
|
|
|
536
|
|
|
|
|
|
|
|
537
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
|
539
|
|
|
|
|
|
|
|
540
|
|
|
|
|
|
|
=head1 AUTHOR
|
541
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
KnowZero
|
543
|
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
=head1 BUGS
|
545
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
Please report any bugs or feature requests to C, or through
|
547
|
|
|
|
|
|
|
the web interface at L. I will be notified, and then you'll
|
548
|
|
|
|
|
|
|
automatically be notified of progress on your bug as I make changes.
|
549
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
|
551
|
|
|
|
|
|
|
|
552
|
|
|
|
|
|
|
|
553
|
|
|
|
|
|
|
=head1 SUPPORT
|
554
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
You can find documentation for this module with the perldoc command.
|
556
|
|
|
|
|
|
|
|
557
|
|
|
|
|
|
|
perldoc Crypt::AES::CTR
|
558
|
|
|
|
|
|
|
|
559
|
|
|
|
|
|
|
|
560
|
|
|
|
|
|
|
You can also look for information at:
|
561
|
|
|
|
|
|
|
|
562
|
|
|
|
|
|
|
=over 4
|
563
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
=item * RT: CPAN's request tracker (report bugs here)
|
565
|
|
|
|
|
|
|
|
566
|
|
|
|
|
|
|
L
|
567
|
|
|
|
|
|
|
|
568
|
|
|
|
|
|
|
=item * AnnoCPAN: Annotated CPAN documentation
|
569
|
|
|
|
|
|
|
|
570
|
|
|
|
|
|
|
L
|
571
|
|
|
|
|
|
|
|
572
|
|
|
|
|
|
|
=item * CPAN Ratings
|
573
|
|
|
|
|
|
|
|
574
|
|
|
|
|
|
|
L
|
575
|
|
|
|
|
|
|
|
576
|
|
|
|
|
|
|
=item * Search CPAN
|
577
|
|
|
|
|
|
|
|
578
|
|
|
|
|
|
|
L
|
579
|
|
|
|
|
|
|
|
580
|
|
|
|
|
|
|
=back
|
581
|
|
|
|
|
|
|
|
582
|
|
|
|
|
|
|
|
583
|
|
|
|
|
|
|
=head1 ACKNOWLEDGEMENTS
|
584
|
|
|
|
|
|
|
|
585
|
|
|
|
|
|
|
|
586
|
|
|
|
|
|
|
=head1 LICENSE AND COPYRIGHT
|
587
|
|
|
|
|
|
|
|
588
|
|
|
|
|
|
|
This is an unofficial port of Chris Veness' AES implementation
|
589
|
|
|
|
|
|
|
Copyright (C) Chris Veness 2005-2011. Right of free use is granted for all commercial or non-commercial use under CC-BY 3.0 licence. No warranty of any form is offered.
|
590
|
|
|
|
|
|
|
|
591
|
|
|
|
|
|
|
Released under the
|
592
|
|
|
|
|
|
|
L
|
593
|
|
|
|
|
|
|
Creative Commons Attribution 3.0 Unported License
|
594
|
|
|
|
|
|
|
|
595
|
|
|
|
|
|
|
For more information:
|
596
|
|
|
|
|
|
|
L
|
597
|
|
|
|
|
|
|
|
598
|
|
|
|
|
|
|
=cut
|
599
|
|
|
|
|
|
|
|
600
|
|
|
|
|
|
|
1; # End of Crypt::AES::CTR
|