line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Crypt::OICQ; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
# $Id: OICQ.pm,v 1.4 2006/01/20 21:31:27 tans Exp $ |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
# Copyright (c) 2002-2006 Shufeng Tan. All rights reserved. |
6
|
|
|
|
|
|
|
# |
7
|
|
|
|
|
|
|
# This package is free software and is provided "as is" without express |
8
|
|
|
|
|
|
|
# or implied warranty. It may be used, redistributed and/or modified |
9
|
|
|
|
|
|
|
# under the terms of the Perl Artistic License (see |
10
|
|
|
|
|
|
|
# http://www.perl.com/perl/misc/Artistic.html) |
11
|
|
|
|
|
|
|
|
12
|
1
|
|
|
1
|
|
27903
|
use 5.008; |
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
159
|
|
13
|
1
|
|
|
1
|
|
7
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
48
|
|
14
|
1
|
|
|
1
|
|
7
|
use warnings; |
|
1
|
|
|
|
|
7
|
|
|
1
|
|
|
|
|
174
|
|
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
our $VERSION = '1.1'; |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
our @ISA = qw(Exporter); |
19
|
|
|
|
|
|
|
our @EXPORT_OK = qw(encrypt decrypt); |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
sub new { |
22
|
0
|
|
|
0
|
0
|
0
|
my ($class) = @_; |
23
|
0
|
|
|
|
|
0
|
bless {}, $class; |
24
|
|
|
|
|
|
|
} |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
my $TEA_ROUNDS = 0x10; |
27
|
|
|
|
|
|
|
my $TEA_DELTA = 0x9E3779B9; |
28
|
|
|
|
|
|
|
my $TEA_SUM = 0xE3779B90; |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
sub tea_decrypt { |
31
|
1
|
|
|
1
|
|
1053
|
use integer; |
|
1
|
|
|
|
|
11
|
|
|
1
|
|
|
|
|
6
|
|
32
|
1077498
|
|
|
1077498
|
0
|
1991682
|
my ($c_block, $key) = @_; |
33
|
1077498
|
|
|
|
|
2316640
|
my ($y, $z) = unpack("NN", $c_block); |
34
|
1077498
|
|
|
|
|
2647621
|
my ($a, $b, $c, $d) = unpack("NNNN", $key); |
35
|
1077498
|
|
|
|
|
1475940
|
my $sum = $TEA_SUM; |
36
|
1077498
|
|
|
|
|
1365143
|
my $n = $TEA_ROUNDS; |
37
|
1077498
|
|
|
|
|
2627426
|
while ($n-- > 0) { |
38
|
17239968
|
|
|
|
|
29407848
|
$z -= ($y<<4)+$c ^ $y+$sum ^ (0x07ffffff & ($y>>5))+$d; |
39
|
17239968
|
|
|
|
|
28372815
|
$y -= ($z<<4)+$a ^ $z+$sum ^ (0x07ffffff & ($z>>5))+$b; |
40
|
17239968
|
|
|
|
|
38392354
|
$sum -= $TEA_DELTA; |
41
|
|
|
|
|
|
|
} |
42
|
1077498
|
|
|
|
|
4093057
|
pack("NN", $y, $z); |
43
|
|
|
|
|
|
|
} |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
sub decrypt { |
46
|
16441
|
|
|
16441
|
0
|
103197
|
my ($self, $crypt, $key) = @_; |
47
|
|
|
|
|
|
|
|
48
|
16441
|
|
|
|
|
30960
|
my $crypt_len = length($crypt); |
49
|
16441
|
50
|
33
|
|
|
147998
|
if (($crypt_len % 8) || ($crypt_len < 16)) { |
50
|
0
|
|
|
|
|
0
|
die "Crypt::OICQ::decrypt error: invalid input length $crypt_len\n"; |
51
|
|
|
|
|
|
|
} |
52
|
|
|
|
|
|
|
|
53
|
16441
|
|
|
|
|
41974
|
my $c_buf = substr($crypt, 0, 8); |
54
|
16441
|
|
|
|
|
46678
|
my $p_buf = tea_decrypt($c_buf, $key); |
55
|
16441
|
|
|
|
|
80895
|
my $pad_len = ord(substr($p_buf, 0, 1) & "\007"); |
56
|
16441
|
|
|
|
|
38957
|
my $plain_len = $crypt_len - $pad_len - 10; |
57
|
16441
|
|
|
|
|
32822
|
my $plain = $p_buf; |
58
|
16441
|
|
|
|
|
26166
|
my $pre_plain = $p_buf; |
59
|
16441
|
|
|
|
|
40553
|
my $pre_crypt = $c_buf; |
60
|
|
|
|
|
|
|
|
61
|
16441
|
|
|
|
|
60628
|
for (my $i = 8; $i < $crypt_len; $i += 8) { |
62
|
1061057
|
|
|
|
|
1839930
|
$c_buf = substr($crypt, $i, 8); |
63
|
1061057
|
|
|
|
|
2724090
|
$p_buf = tea_decrypt($c_buf ^ $pre_plain, $key); |
64
|
1061057
|
|
|
|
|
1994537
|
$pre_plain = $p_buf; |
65
|
1061057
|
|
|
|
|
1572343
|
$p_buf ^= $pre_crypt; |
66
|
1061057
|
|
|
|
|
1500597
|
$plain .= $p_buf; |
67
|
1061057
|
|
|
|
|
3281381
|
$pre_crypt = $c_buf; |
68
|
|
|
|
|
|
|
} |
69
|
16441
|
50
|
|
|
|
75346
|
if (substr($plain, -7, 7) ne "\0\0\0\0\0\0\0") { |
70
|
0
|
|
|
|
|
0
|
die "Crypt::OICQ::decrypt error: data dumped\n", |
71
|
|
|
|
|
|
|
"crypt: ", unpack("H*", $crypt), "\n", |
72
|
|
|
|
|
|
|
"key: ", unpack("H*", $key), "\n", |
73
|
|
|
|
|
|
|
"plain: ", unpack("H*", $plain), "\n"; |
74
|
|
|
|
|
|
|
} |
75
|
16441
|
|
|
|
|
186891
|
return substr($plain, -7-$plain_len, $plain_len); |
76
|
|
|
|
|
|
|
} |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
sub tea_encrypt { |
79
|
1
|
|
|
1
|
|
508
|
use integer; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
5
|
|
80
|
1077412
|
|
|
1077412
|
0
|
1755836
|
my ($p_block, $key) = @_; |
81
|
1077412
|
|
|
|
|
2331846
|
my ($y, $z) = unpack("NN", $p_block); |
82
|
1077412
|
|
|
|
|
2570178
|
my ($a, $b, $c, $d) = unpack("NNNN", $key); |
83
|
1077412
|
|
|
|
|
1518779
|
my $sum = 0; |
84
|
1077412
|
|
|
|
|
1363671
|
my $n = $TEA_ROUNDS; |
85
|
1077412
|
|
|
|
|
2855006
|
while ($n-- > 0) { |
86
|
17238592
|
|
|
|
|
20767225
|
$sum += $TEA_DELTA; |
87
|
17238592
|
|
|
|
|
29308756
|
$y += ($z<<4)+$a ^ $z+$sum ^ (0x07ffffff & ($z>>5))+$b; |
88
|
17238592
|
|
|
|
|
46945233
|
$z += ($y<<4)+$c ^ $y+$sum ^ (0x07ffffff & ($y>>5))+$d; |
89
|
|
|
|
|
|
|
} |
90
|
1077412
|
|
|
|
|
3715105
|
pack("NN", $y, $z); |
91
|
|
|
|
|
|
|
} |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
sub encrypt { |
94
|
16429
|
|
|
16429
|
0
|
148626
|
my ($self, $plain, $key) = @_; |
95
|
16429
|
|
|
|
|
44323
|
my $plain_len = length($plain); |
96
|
16429
|
|
|
|
|
47419
|
my $head_pad_len = ($plain_len + 10) % 8; |
97
|
16429
|
100
|
|
|
|
53607
|
$head_pad_len = 8 - $head_pad_len if $head_pad_len; |
98
|
16429
|
|
|
|
|
71423
|
my $padded_plain = chr(0xa8 + $head_pad_len) . |
99
|
|
|
|
|
|
|
rand_str(2+$head_pad_len) . |
100
|
|
|
|
|
|
|
#(chr(0xad) x (2 + $head_pad_len)) . |
101
|
|
|
|
|
|
|
$plain . ("\0" x 7); |
102
|
16429
|
|
|
|
|
46094
|
my $padded_plain_len = length($padded_plain); |
103
|
16429
|
|
|
|
|
25773
|
my $crypt = ""; |
104
|
16429
|
|
|
|
|
37326
|
my $pre_plain = "\0" x 8; |
105
|
16429
|
|
|
|
|
26986
|
my $pre_crypt = $pre_plain; |
106
|
16429
|
|
|
|
|
52833
|
for (my $i = 0; $i < $padded_plain_len; $i += 8) { |
107
|
1077412
|
|
|
|
|
2140581
|
my $p_buf = substr($padded_plain, $i, 8) ^ $pre_crypt; |
108
|
1077412
|
|
|
|
|
2221115
|
my $c_buf = tea_encrypt($p_buf, $key); |
109
|
1077412
|
|
|
|
|
1871475
|
$c_buf ^= $pre_plain; |
110
|
1077412
|
|
|
|
|
1525583
|
$crypt .= $c_buf; |
111
|
1077412
|
|
|
|
|
1511677
|
$pre_crypt = $c_buf; |
112
|
1077412
|
|
|
|
|
3217615
|
$pre_plain = $p_buf; |
113
|
|
|
|
|
|
|
} |
114
|
16429
|
|
|
|
|
158325
|
return $crypt; |
115
|
|
|
|
|
|
|
} |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
sub rand_str { |
118
|
32829
|
|
|
32829
|
0
|
2077281
|
my $len = pop; |
119
|
32829
|
|
|
|
|
7017403
|
join('', map(pack("C", rand(0xff)), 1..$len)); |
120
|
|
|
|
|
|
|
} |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
1; |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
__END__ |