ruby-aes-table1 1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +6 -0
- data/COPYING +20 -0
- data/README +77 -0
- data/Rakefile +154 -0
- data/doc/rdoc/classes/Aes.html +494 -0
- data/doc/rdoc/classes/AesAlg.html +731 -0
- data/doc/rdoc/classes/AesCons.html +168 -0
- data/doc/rdoc/created.rid +1 -0
- data/doc/rdoc/files/CHANGELOG.html +117 -0
- data/doc/rdoc/files/COPYING.html +129 -0
- data/doc/rdoc/files/README.html +235 -0
- data/doc/rdoc/files/lib/ruby-aes/aes_alg_rb.html +108 -0
- data/doc/rdoc/files/lib/ruby-aes/aes_cons_rb.html +101 -0
- data/doc/rdoc/files/lib/ruby-aes_rb.html +108 -0
- data/doc/rdoc/fr_class_index.html +29 -0
- data/doc/rdoc/fr_file_index.html +32 -0
- data/doc/rdoc/fr_method_index.html +52 -0
- data/doc/rdoc/index.html +24 -0
- data/doc/rdoc/rdoc-style.css +208 -0
- data/examples/encrypt_block.rb +22 -0
- data/examples/encrypt_buffer.rb +24 -0
- data/examples/encrypt_stream.rb +39 -0
- data/examples/example_helper.rb +27 -0
- data/lib/ruby-aes/aes_alg.rb +360 -0
- data/lib/ruby-aes/aes_cons.rb +478 -0
- data/lib/ruby-aes.rb +162 -0
- data/test/KAT_MCT/aes_kat_mct.rb +386 -0
- data/test/KAT_MCT/rijndael-vals.zip +0 -0
- data/test/KAT_MCT/table.128 +128 -0
- data/test/KAT_MCT/table.192 +128 -0
- data/test/KAT_MCT/table.256 +128 -0
- data/test/test_helper.rb +14 -0
- data/test/test_ruby-aes.rb +113 -0
- metadata +98 -0
@@ -0,0 +1,208 @@
|
|
1
|
+
|
2
|
+
body {
|
3
|
+
font-family: Verdana,Arial,Helvetica,sans-serif;
|
4
|
+
font-size: 90%;
|
5
|
+
margin: 0;
|
6
|
+
margin-left: 40px;
|
7
|
+
padding: 0;
|
8
|
+
background: white;
|
9
|
+
}
|
10
|
+
|
11
|
+
h1,h2,h3,h4 { margin: 0; color: #efefef; background: transparent; }
|
12
|
+
h1 { font-size: 150%; }
|
13
|
+
h2,h3,h4 { margin-top: 1em; }
|
14
|
+
|
15
|
+
a { background: #eef; color: #039; text-decoration: none; }
|
16
|
+
a:hover { background: #039; color: #eef; }
|
17
|
+
|
18
|
+
/* Override the base stylesheet's Anchor inside a table cell */
|
19
|
+
td > a {
|
20
|
+
background: transparent;
|
21
|
+
color: #039;
|
22
|
+
text-decoration: none;
|
23
|
+
}
|
24
|
+
|
25
|
+
/* and inside a section title */
|
26
|
+
.section-title > a {
|
27
|
+
background: transparent;
|
28
|
+
color: #eee;
|
29
|
+
text-decoration: none;
|
30
|
+
}
|
31
|
+
|
32
|
+
/* === Structural elements =================================== */
|
33
|
+
|
34
|
+
div#index {
|
35
|
+
margin: 0;
|
36
|
+
margin-left: -40px;
|
37
|
+
padding: 0;
|
38
|
+
font-size: 90%;
|
39
|
+
}
|
40
|
+
|
41
|
+
|
42
|
+
div#index a {
|
43
|
+
margin-left: 0.7em;
|
44
|
+
}
|
45
|
+
|
46
|
+
div#index .section-bar {
|
47
|
+
margin-left: 0px;
|
48
|
+
padding-left: 0.7em;
|
49
|
+
background: #ccc;
|
50
|
+
font-size: small;
|
51
|
+
}
|
52
|
+
|
53
|
+
|
54
|
+
div#classHeader, div#fileHeader {
|
55
|
+
width: auto;
|
56
|
+
color: white;
|
57
|
+
padding: 0.5em 1.5em 0.5em 1.5em;
|
58
|
+
margin: 0;
|
59
|
+
margin-left: -40px;
|
60
|
+
border-bottom: 3px solid #006;
|
61
|
+
}
|
62
|
+
|
63
|
+
div#classHeader a, div#fileHeader a {
|
64
|
+
background: inherit;
|
65
|
+
color: white;
|
66
|
+
}
|
67
|
+
|
68
|
+
div#classHeader td, div#fileHeader td {
|
69
|
+
background: inherit;
|
70
|
+
color: white;
|
71
|
+
}
|
72
|
+
|
73
|
+
|
74
|
+
div#fileHeader {
|
75
|
+
background: #057;
|
76
|
+
}
|
77
|
+
|
78
|
+
div#classHeader {
|
79
|
+
background: #048;
|
80
|
+
}
|
81
|
+
|
82
|
+
|
83
|
+
.class-name-in-header {
|
84
|
+
font-size: 180%;
|
85
|
+
font-weight: bold;
|
86
|
+
}
|
87
|
+
|
88
|
+
|
89
|
+
div#bodyContent {
|
90
|
+
padding: 0 1.5em 0 1.5em;
|
91
|
+
}
|
92
|
+
|
93
|
+
div#description {
|
94
|
+
padding: 0.5em 1.5em;
|
95
|
+
background: #efefef;
|
96
|
+
border: 1px dotted #999;
|
97
|
+
}
|
98
|
+
|
99
|
+
div#description h1,h2,h3,h4,h5,h6 {
|
100
|
+
color: #125;;
|
101
|
+
background: transparent;
|
102
|
+
}
|
103
|
+
|
104
|
+
div#validator-badges {
|
105
|
+
text-align: center;
|
106
|
+
}
|
107
|
+
div#validator-badges img { border: 0; }
|
108
|
+
|
109
|
+
div#copyright {
|
110
|
+
color: #333;
|
111
|
+
background: #efefef;
|
112
|
+
font: 0.75em sans-serif;
|
113
|
+
margin-top: 5em;
|
114
|
+
margin-bottom: 0;
|
115
|
+
padding: 0.5em 2em;
|
116
|
+
}
|
117
|
+
|
118
|
+
|
119
|
+
/* === Classes =================================== */
|
120
|
+
|
121
|
+
table.header-table {
|
122
|
+
color: white;
|
123
|
+
font-size: small;
|
124
|
+
}
|
125
|
+
|
126
|
+
.type-note {
|
127
|
+
font-size: small;
|
128
|
+
color: #DEDEDE;
|
129
|
+
}
|
130
|
+
|
131
|
+
.xxsection-bar {
|
132
|
+
background: #eee;
|
133
|
+
color: #333;
|
134
|
+
padding: 3px;
|
135
|
+
}
|
136
|
+
|
137
|
+
.section-bar {
|
138
|
+
color: #333;
|
139
|
+
border-bottom: 1px solid #999;
|
140
|
+
margin-left: -20px;
|
141
|
+
}
|
142
|
+
|
143
|
+
|
144
|
+
.section-title {
|
145
|
+
background: #79a;
|
146
|
+
color: #eee;
|
147
|
+
padding: 3px;
|
148
|
+
margin-top: 2em;
|
149
|
+
margin-left: -30px;
|
150
|
+
border: 1px solid #999;
|
151
|
+
}
|
152
|
+
|
153
|
+
.top-aligned-row { vertical-align: top }
|
154
|
+
.bottom-aligned-row { vertical-align: bottom }
|
155
|
+
|
156
|
+
/* --- Context section classes ----------------------- */
|
157
|
+
|
158
|
+
.context-row { }
|
159
|
+
.context-item-name { font-family: monospace; font-weight: bold; color: black; }
|
160
|
+
.context-item-value { font-size: small; color: #448; }
|
161
|
+
.context-item-desc { color: #333; padding-left: 2em; }
|
162
|
+
|
163
|
+
/* --- Method classes -------------------------- */
|
164
|
+
.method-detail {
|
165
|
+
background: #efefef;
|
166
|
+
padding: 0;
|
167
|
+
margin-top: 0.5em;
|
168
|
+
margin-bottom: 1em;
|
169
|
+
border: 1px dotted #ccc;
|
170
|
+
}
|
171
|
+
.method-heading {
|
172
|
+
color: black;
|
173
|
+
background: #ccc;
|
174
|
+
border-bottom: 1px solid #666;
|
175
|
+
padding: 0.2em 0.5em 0 0.5em;
|
176
|
+
}
|
177
|
+
.method-signature { color: black; background: inherit; }
|
178
|
+
.method-name { font-weight: bold; }
|
179
|
+
.method-args { font-style: italic; }
|
180
|
+
.method-description { padding: 0 0.5em 0 0.5em; }
|
181
|
+
|
182
|
+
/* --- Source code sections -------------------- */
|
183
|
+
|
184
|
+
a.source-toggle { font-size: 90%; }
|
185
|
+
div.method-source-code {
|
186
|
+
background: #262626;
|
187
|
+
color: #ffdead;
|
188
|
+
margin: 1em;
|
189
|
+
padding: 0.5em;
|
190
|
+
border: 1px dashed #999;
|
191
|
+
overflow: hidden;
|
192
|
+
}
|
193
|
+
|
194
|
+
div.method-source-code pre { color: #ffdead; overflow: hidden; }
|
195
|
+
|
196
|
+
/* --- Ruby keyword styles --------------------- */
|
197
|
+
|
198
|
+
.standalone-code { background: #221111; color: #ffdead; overflow: hidden; }
|
199
|
+
|
200
|
+
.ruby-constant { color: #7fffd4; background: transparent; }
|
201
|
+
.ruby-keyword { color: #00ffff; background: transparent; }
|
202
|
+
.ruby-ivar { color: #eedd82; background: transparent; }
|
203
|
+
.ruby-operator { color: #00ffee; background: transparent; }
|
204
|
+
.ruby-identifier { color: #ffdead; background: transparent; }
|
205
|
+
.ruby-node { color: #ffa07a; background: transparent; }
|
206
|
+
.ruby-comment { color: #b22222; font-weight: bold; background: transparent; }
|
207
|
+
.ruby-regexp { color: #ffa07a; background: transparent; }
|
208
|
+
.ruby-value { color: #7fffd4; background: transparent; }
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'ruby-aes'
|
4
|
+
require 'example_helper'
|
5
|
+
|
6
|
+
class RubyAES_block
|
7
|
+
|
8
|
+
include RubyAES_helper
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
setup
|
12
|
+
pt = "0123467890ABCDEF"
|
13
|
+
puts "Using #{@kl}-#{@mode} encryption/decryption"
|
14
|
+
puts "Plaintext is: #{pt} (a block should be 16 octets)"
|
15
|
+
ct = Aes.encrypt_block(@kl, @mode, @keys[@kl], @iv, pt)
|
16
|
+
puts "Ciphertext (unpacked) is: #{ct.unpack("H*").first}"
|
17
|
+
npt = Aes.decrypt_block(@kl, @mode, @keys[@kl], @iv, ct)
|
18
|
+
puts "Decrypted ciphertext is: #{npt} (should be: #{pt})"
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
RubyAES_block.new
|
@@ -0,0 +1,24 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'ruby-aes'
|
4
|
+
require 'example_helper'
|
5
|
+
|
6
|
+
class RubyAES_buffer
|
7
|
+
|
8
|
+
include RubyAES_helper
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
setup
|
12
|
+
puts "Using #{@kl}-#{@mode} encryption/decryption"
|
13
|
+
pt = "The quick brown fox jumps over the lazy dog"
|
14
|
+
puts "Plaintext is: '#{pt}'"
|
15
|
+
puts "(a buffer will be padded so that its length will be a multiple of 16)"
|
16
|
+
ct = Aes.encrypt_buffer(@kl, @mode, @keys[@kl], @iv, pt)
|
17
|
+
puts "Ciphertext (unpacked) is: #{ct.unpack("H*").first}"
|
18
|
+
npt = Aes.decrypt_buffer(@kl, @mode, @keys[@kl], @iv, ct)
|
19
|
+
puts "Decrypted ciphertext is: '#{npt}'"
|
20
|
+
puts "(should be: '#{pt}')"
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
RubyAES_buffer.new
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'ruby-aes'
|
4
|
+
require 'example_helper'
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
class RubyAES_stream
|
8
|
+
|
9
|
+
include RubyAES_helper
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
setup
|
13
|
+
puts "Using #{@kl}-#{@mode} encryption/decryption"
|
14
|
+
file = "_ruby-aes_encrypt_stream_"
|
15
|
+
|
16
|
+
sin = File.open(file, "w+b")
|
17
|
+
sin.puts "The quick brown fox jumps over the lazy dog"
|
18
|
+
sin.rewind
|
19
|
+
sout = File.open("#{file}.aes", "w+b")
|
20
|
+
Aes.encrypt_stream(@kl, @mode, @keys[@kl], @iv, sin, sout)
|
21
|
+
sin.close
|
22
|
+
sout.close
|
23
|
+
|
24
|
+
sin = File.open("#{file}.aes", "rb")
|
25
|
+
sout = File.open("#{file}.plain", "w+b")
|
26
|
+
Aes.decrypt_stream(@kl, @mode, @keys[@kl], @iv, sin, sout)
|
27
|
+
sin.close
|
28
|
+
sout.close
|
29
|
+
|
30
|
+
if IO.read(file) == IO.read("#{file}.plain")
|
31
|
+
puts "The decrypted file is exactly the same as the original one"
|
32
|
+
else
|
33
|
+
puts "The decrypted file differs from the orginal one"
|
34
|
+
end
|
35
|
+
FileUtils.rm_f [ file, "#{file}.aes", "#{file}.plain" ]
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
RubyAES_stream.new
|
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module RubyAES_helper
|
4
|
+
|
5
|
+
KEY_LENGTH = [128,192,256].freeze
|
6
|
+
MODES = ['ECB','CBC','OFB','CFB'].freeze
|
7
|
+
|
8
|
+
def random_fill(n, buffer)
|
9
|
+
n.times do
|
10
|
+
buffer << rand(256).chr
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def setup
|
15
|
+
@keys = {}
|
16
|
+
KEY_LENGTH.each do |kl|
|
17
|
+
@keys[kl] = ""
|
18
|
+
random_fill(kl/8, @keys[kl])
|
19
|
+
end
|
20
|
+
|
21
|
+
@iv = ""; random_fill(16, @iv)
|
22
|
+
@pt = ""; random_fill(64, @pt)
|
23
|
+
@kl = KEY_LENGTH[(rand * KEY_LENGTH.length).to_i]
|
24
|
+
@mode = MODES[(rand * MODES.length).to_i]
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,360 @@
|
|
1
|
+
=begin
|
2
|
+
This file is a part of ruby-aes <http://rubyforge.org/projects/ruby-aes>
|
3
|
+
Written by Alex Boussinet <alex.boussinet@gmail.com>
|
4
|
+
|
5
|
+
This version is derived from the Optimised ANSI C code
|
6
|
+
Authors of C version:
|
7
|
+
Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
|
8
|
+
Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
|
9
|
+
Paulo Barreto <paulo.barreto@terra.com.br>
|
10
|
+
=end
|
11
|
+
|
12
|
+
require 'ruby-aes/aes_cons'
|
13
|
+
|
14
|
+
class AesAlg
|
15
|
+
include AesCons
|
16
|
+
|
17
|
+
def encryption_key_schedule(key)
|
18
|
+
i = 0
|
19
|
+
@rk = []
|
20
|
+
@rk[0] = key[0] << 24 | key[1] << 16 | key[2] << 8 | key[3]
|
21
|
+
@rk[1] = key[4] << 24 | key[5] << 16 | key[6] << 8 | key[7]
|
22
|
+
@rk[2] = key[8] << 24 | key[9] << 16 | key[10] << 8 | key[11]
|
23
|
+
@rk[3] = key[12] << 24 | key[13] << 16 | key[14] << 8 | key[15]
|
24
|
+
if @kl == 128
|
25
|
+
j = 0
|
26
|
+
loop { temp = @rk[3+j]
|
27
|
+
@rk[4+j] = @rk[0+j] ^
|
28
|
+
(Te4[(temp >> 16) & 0xff] & 0xff000000) ^
|
29
|
+
(Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
|
30
|
+
(Te4[(temp ) & 0xff] & 0x0000ff00) ^
|
31
|
+
(Te4[(temp >> 24) ] & 0x000000ff) ^ RCON[i]
|
32
|
+
@rk[5+j] = @rk[1+j] ^ @rk[4+j]
|
33
|
+
@rk[6+j] = @rk[2+j] ^ @rk[5+j]
|
34
|
+
@rk[7+j] = @rk[3+j] ^ @rk[6+j]
|
35
|
+
i += 1
|
36
|
+
return if (i == 10)
|
37
|
+
j += 4
|
38
|
+
}
|
39
|
+
end
|
40
|
+
@rk[4] = key[16] << 24 | key[17] << 16 | key[18] << 8 | key[19]
|
41
|
+
@rk[5] = key[20] << 24 | key[21] << 16 | key[22] << 8 | key[23]
|
42
|
+
if (@kl == 192)
|
43
|
+
j = 0
|
44
|
+
loop { temp = @rk[ 5+j]
|
45
|
+
@rk[ 6+j] = @rk[ 0+j] ^
|
46
|
+
(Te4[(temp >> 16) & 0xff] & 0xff000000) ^
|
47
|
+
(Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
|
48
|
+
(Te4[(temp ) & 0xff] & 0x0000ff00) ^
|
49
|
+
(Te4[(temp >> 24) ] & 0x000000ff) ^ RCON[i]
|
50
|
+
@rk[ 7+j] = @rk[ 1+j] ^ @rk[ 6+j]
|
51
|
+
@rk[ 8+j] = @rk[ 2+j] ^ @rk[ 7+j]
|
52
|
+
@rk[ 9+j] = @rk[ 3+j] ^ @rk[ 8+j]
|
53
|
+
i += 1
|
54
|
+
return if (i == 8)
|
55
|
+
@rk[10+j] = @rk[ 4+j] ^ @rk[ 9+j]
|
56
|
+
@rk[11+j] = @rk[ 5+j] ^ @rk[10+j]
|
57
|
+
j += 6
|
58
|
+
}
|
59
|
+
end
|
60
|
+
@rk[6] = key[24] << 24 | key[25] << 16 | key[26] << 8 | key[27]
|
61
|
+
@rk[7] = key[28] << 24 | key[29] << 16 | key[30] << 8 | key[31]
|
62
|
+
if (@kl == 256)
|
63
|
+
j = 0
|
64
|
+
loop { temp = @rk[ 7+j]
|
65
|
+
@rk[ 8+j] = @rk[ 0+j] ^
|
66
|
+
(Te4[(temp >> 16) & 0xff] & 0xff000000) ^
|
67
|
+
(Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
|
68
|
+
(Te4[(temp ) & 0xff] & 0x0000ff00) ^
|
69
|
+
(Te4[(temp >> 24) ] & 0x000000ff) ^ RCON[i]
|
70
|
+
@rk[ 9+j] = @rk[ 1+j] ^ @rk[ 8+j]
|
71
|
+
@rk[10+j] = @rk[ 2+j] ^ @rk[ 9+j]
|
72
|
+
@rk[11+j] = @rk[ 3+j] ^ @rk[10+j]
|
73
|
+
i += 1
|
74
|
+
return if (i == 7)
|
75
|
+
temp = @rk[11+j]
|
76
|
+
@rk[12+j] = @rk[ 4+j] ^
|
77
|
+
(Te4[(temp >> 24) ] & 0xff000000) ^
|
78
|
+
(Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
|
79
|
+
(Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^
|
80
|
+
(Te4[(temp ) & 0xff] & 0x000000ff)
|
81
|
+
@rk[13+j] = @rk[ 5+j] ^ @rk[12+j]
|
82
|
+
@rk[14+j] = @rk[ 6+j] ^ @rk[13+j]
|
83
|
+
@rk[15+j] = @rk[ 7+j] ^ @rk[14+j]
|
84
|
+
j += 8
|
85
|
+
}
|
86
|
+
end
|
87
|
+
end
|
88
|
+
protected :encryption_key_schedule
|
89
|
+
|
90
|
+
def decryption_key_schedule(key)
|
91
|
+
# expand the cipher key:
|
92
|
+
encryption_key_schedule(key)
|
93
|
+
@ek = @rk.dup
|
94
|
+
# invert the order of the round keys:
|
95
|
+
j = 4 * @nr
|
96
|
+
i = 0
|
97
|
+
loop { break if i >= j
|
98
|
+
temp = @rk[i]
|
99
|
+
@rk[i] = @rk[j]
|
100
|
+
@rk[j] = temp
|
101
|
+
temp = @rk[i + 1]
|
102
|
+
@rk[i + 1] = @rk[j + 1]
|
103
|
+
@rk[j + 1] = temp
|
104
|
+
temp = @rk[i + 2]
|
105
|
+
@rk[i + 2] = @rk[j + 2]
|
106
|
+
@rk[j + 2] = temp
|
107
|
+
temp = @rk[i + 3]
|
108
|
+
@rk[i + 3] = @rk[j + 3]
|
109
|
+
@rk[j + 3] = temp
|
110
|
+
i += 4
|
111
|
+
j -= 4
|
112
|
+
}
|
113
|
+
# apply the inverse MixColumn transform
|
114
|
+
# to all round keys but the first and the last:
|
115
|
+
j = 0
|
116
|
+
1.upto(@nr-1) { |i| j += 4
|
117
|
+
@rk[0+j] =
|
118
|
+
Td0[Te4[(@rk[0+j] >> 24) ] & 0xff] ^
|
119
|
+
Td1[Te4[(@rk[0+j] >> 16) & 0xff] & 0xff] ^
|
120
|
+
Td2[Te4[(@rk[0+j] >> 8) & 0xff] & 0xff] ^
|
121
|
+
Td3[Te4[(@rk[0+j] ) & 0xff] & 0xff]
|
122
|
+
@rk[1+j] =
|
123
|
+
Td0[Te4[(@rk[1+j] >> 24) ] & 0xff] ^
|
124
|
+
Td1[Te4[(@rk[1+j] >> 16) & 0xff] & 0xff] ^
|
125
|
+
Td2[Te4[(@rk[1+j] >> 8) & 0xff] & 0xff] ^
|
126
|
+
Td3[Te4[(@rk[1+j] ) & 0xff] & 0xff]
|
127
|
+
@rk[2+j] =
|
128
|
+
Td0[Te4[(@rk[2+j] >> 24) ] & 0xff] ^
|
129
|
+
Td1[Te4[(@rk[2+j] >> 16) & 0xff] & 0xff] ^
|
130
|
+
Td2[Te4[(@rk[2+j] >> 8) & 0xff] & 0xff] ^
|
131
|
+
Td3[Te4[(@rk[2+j] ) & 0xff] & 0xff]
|
132
|
+
@rk[3+j] =
|
133
|
+
Td0[Te4[(@rk[3+j] >> 24) ] & 0xff] ^
|
134
|
+
Td1[Te4[(@rk[3+j] >> 16) & 0xff] & 0xff] ^
|
135
|
+
Td2[Te4[(@rk[3+j] >> 8) & 0xff] & 0xff] ^
|
136
|
+
Td3[Te4[(@rk[3+j] ) & 0xff] & 0xff]
|
137
|
+
}
|
138
|
+
end
|
139
|
+
protected :decryption_key_schedule
|
140
|
+
|
141
|
+
def _encrypt_block(pt)
|
142
|
+
t0 = t1 = t2 = t3 = nil
|
143
|
+
# map byte array block to cipher state and add initial round key:
|
144
|
+
s0 = (pt[ 0] << 24 | pt[ 1] << 16 | pt[ 2] << 8 | pt[ 3]) ^ @ek[0]
|
145
|
+
s1 = (pt[ 4] << 24 | pt[ 5] << 16 | pt[ 6] << 8 | pt[ 7]) ^ @ek[1]
|
146
|
+
s2 = (pt[ 8] << 24 | pt[ 9] << 16 | pt[10] << 8 | pt[11]) ^ @ek[2]
|
147
|
+
s3 = (pt[12] << 24 | pt[13] << 16 | pt[14] << 8 | pt[15]) ^ @ek[3]
|
148
|
+
r = @nr >> 1
|
149
|
+
j = 0
|
150
|
+
loop {
|
151
|
+
t0 = Te0[(s0 >> 24) ] ^ Te1[(s1 >> 16) & 0xff] ^
|
152
|
+
Te2[(s2 >> 8) & 0xff] ^ Te3[(s3 ) & 0xff] ^ @ek[4+j]
|
153
|
+
t1 = Te0[(s1 >> 24) ] ^ Te1[(s2 >> 16) & 0xff] ^
|
154
|
+
Te2[(s3 >> 8) & 0xff] ^ Te3[(s0 ) & 0xff] ^ @ek[5+j]
|
155
|
+
t2 = Te0[(s2 >> 24) ] ^ Te1[(s3 >> 16) & 0xff] ^
|
156
|
+
Te2[(s0 >> 8) & 0xff] ^ Te3[(s1 ) & 0xff] ^ @ek[6+j]
|
157
|
+
t3 = Te0[(s3 >> 24) ] ^ Te1[(s0 >> 16) & 0xff] ^
|
158
|
+
Te2[(s1 >> 8) & 0xff] ^ Te3[(s2 ) & 0xff] ^ @ek[7+j]
|
159
|
+
j += 8
|
160
|
+
r -= 1
|
161
|
+
break if r == 0
|
162
|
+
s0 = Te0[(t0 >> 24) ] ^ Te1[(t1 >> 16) & 0xff] ^
|
163
|
+
Te2[(t2 >> 8) & 0xff] ^ Te3[(t3 ) & 0xff] ^ @ek[0+j]
|
164
|
+
s1 = Te0[(t1 >> 24) ] ^ Te1[(t2 >> 16) & 0xff] ^
|
165
|
+
Te2[(t3 >> 8) & 0xff] ^ Te3[(t0 ) & 0xff] ^ @ek[1+j]
|
166
|
+
s2 = Te0[(t2 >> 24) ] ^ Te1[(t3 >> 16) & 0xff] ^
|
167
|
+
Te2[(t0 >> 8) & 0xff] ^ Te3[(t1 ) & 0xff] ^ @ek[2+j]
|
168
|
+
s3 = Te0[(t3 >> 24) ] ^ Te1[(t0 >> 16) & 0xff] ^
|
169
|
+
Te2[(t1 >> 8) & 0xff] ^ Te3[(t2 ) & 0xff] ^ @ek[3+j]
|
170
|
+
}
|
171
|
+
# apply last round and map cipher state to byte array block:
|
172
|
+
s0 = (Te4[(t0>>24)] & 0xff000000) ^ (Te4[(t1>>16)&0xff]&0x00ff0000) ^
|
173
|
+
(Te4[(t2>>8)&0xff]&0x0000ff00) ^ (Te4[(t3)&0xff]&0x000000ff) ^ @ek[0+j]
|
174
|
+
s1 = (Te4[(t1>>24)]&0xff000000) ^ (Te4[(t2>>16)&0xff]&0x00ff0000) ^
|
175
|
+
(Te4[(t3>>8)&0xff]&0x0000ff00) ^ (Te4[(t0)&0xff]&0x000000ff) ^ @ek[1+j]
|
176
|
+
s2 = (Te4[(t2>>24)]&0xff000000) ^ (Te4[(t3>>16)&0xff]&0x00ff0000) ^
|
177
|
+
(Te4[(t0>>8)&0xff]&0x0000ff00) ^ (Te4[(t1)&0xff]&0x000000ff) ^ @ek[2+j]
|
178
|
+
s3 = (Te4[(t3>>24)]&0xff000000) ^ (Te4[(t0>>16)&0xff]&0x00ff0000) ^
|
179
|
+
(Te4[(t1>>8)&0xff]&0x0000ff00) ^ (Te4[(t2)&0xff]&0x000000ff) ^ @ek[3+j]
|
180
|
+
[("%08x%08x%08x%08x" % [s0, s1, s2, s3])].pack("H*")
|
181
|
+
end
|
182
|
+
protected :_encrypt_block
|
183
|
+
|
184
|
+
def _decrypt_block(ct)
|
185
|
+
t0 = t1 = t2 = t3 = nil
|
186
|
+
# map byte array block to cipher state and add initial round key:
|
187
|
+
s0 = (ct[ 0] << 24 | ct[ 1] << 16 | ct[ 2] << 8 | ct[ 3]) ^ @rk[0]
|
188
|
+
s1 = (ct[ 4] << 24 | ct[ 5] << 16 | ct[ 6] << 8 | ct[ 7]) ^ @rk[1]
|
189
|
+
s2 = (ct[ 8] << 24 | ct[ 9] << 16 | ct[10] << 8 | ct[11]) ^ @rk[2]
|
190
|
+
s3 = (ct[12] << 24 | ct[13] << 16 | ct[14] << 8 | ct[15]) ^ @rk[3]
|
191
|
+
r = @nr >> 1
|
192
|
+
j = 0
|
193
|
+
loop {
|
194
|
+
t0 = Td0[(s0 >> 24) ] ^ Td1[(s3 >> 16) & 0xff] ^
|
195
|
+
Td2[(s2 >> 8) & 0xff] ^ Td3[(s1 ) & 0xff] ^ @rk[4+j]
|
196
|
+
t1 = Td0[(s1 >> 24) ] ^ Td1[(s0 >> 16) & 0xff] ^
|
197
|
+
Td2[(s3 >> 8) & 0xff] ^ Td3[(s2 ) & 0xff] ^ @rk[5+j]
|
198
|
+
t2 = Td0[(s2 >> 24) ] ^ Td1[(s1 >> 16) & 0xff] ^
|
199
|
+
Td2[(s0 >> 8) & 0xff] ^ Td3[(s3 ) & 0xff] ^ @rk[6+j]
|
200
|
+
t3 = Td0[(s3 >> 24) ] ^ Td1[(s2 >> 16) & 0xff] ^
|
201
|
+
Td2[(s1 >> 8) & 0xff] ^ Td3[(s0 ) & 0xff] ^ @rk[7+j]
|
202
|
+
j += 8
|
203
|
+
r -= 1
|
204
|
+
break if r == 0
|
205
|
+
s0 = Td0[(t0 >> 24) ] ^ Td1[(t3 >> 16) & 0xff] ^
|
206
|
+
Td2[(t2 >> 8) & 0xff] ^ Td3[(t1 ) & 0xff] ^ @rk[0+j]
|
207
|
+
s1 = Td0[(t1 >> 24) ] ^ Td1[(t0 >> 16) & 0xff] ^
|
208
|
+
Td2[(t3 >> 8) & 0xff] ^ Td3[(t2 ) & 0xff] ^ @rk[1+j]
|
209
|
+
s2 = Td0[(t2 >> 24) ] ^ Td1[(t1 >> 16) & 0xff] ^
|
210
|
+
Td2[(t0 >> 8) & 0xff] ^ Td3[(t3 ) & 0xff] ^ @rk[2+j]
|
211
|
+
s3 = Td0[(t3 >> 24) ] ^ Td1[(t2 >> 16) & 0xff] ^
|
212
|
+
Td2[(t1 >> 8) & 0xff] ^ Td3[(t0 ) & 0xff] ^ @rk[3+j]
|
213
|
+
}
|
214
|
+
# apply last round and map cipher state to byte array block:
|
215
|
+
s0 = (Td4[(t0>>24)]&0xff000000) ^ (Td4[(t3>>16)&0xff]&0x00ff0000) ^
|
216
|
+
(Td4[(t2>>8)&0xff]&0x0000ff00) ^ (Td4[(t1)&0xff]&0x000000ff) ^ @rk[0+j]
|
217
|
+
s1 = (Td4[(t1>>24)]&0xff000000) ^ (Td4[(t0>>16)&0xff]&0x00ff0000) ^
|
218
|
+
(Td4[(t3>>8)&0xff]&0x0000ff00) ^ (Td4[(t2)&0xff]&0x000000ff) ^ @rk[1+j]
|
219
|
+
s2 = (Td4[(t2>>24)]&0xff000000) ^ (Td4[(t1>>16)&0xff]&0x00ff0000) ^
|
220
|
+
(Td4[(t0>>8)&0xff]&0x0000ff00) ^ (Td4[(t3)&0xff]&0x000000ff) ^ @rk[2+j]
|
221
|
+
s3 = (Td4[(t3>>24)]&0xff000000) ^ (Td4[(t2>>16)&0xff]&0x00ff0000) ^
|
222
|
+
(Td4[(t1>>8)&0xff]&0x0000ff00) ^ (Td4[(t0)&0xff]&0x000000ff) ^ @rk[3+j]
|
223
|
+
[("%08x%08x%08x%08x" % [s0, s1, s2, s3])].pack("H*")
|
224
|
+
end
|
225
|
+
protected :_decrypt_block
|
226
|
+
|
227
|
+
def xor(a,b)
|
228
|
+
c = ""
|
229
|
+
16.times do |i|
|
230
|
+
c << (a[i] ^ b[i]).chr
|
231
|
+
end
|
232
|
+
c
|
233
|
+
end
|
234
|
+
protected :xor
|
235
|
+
|
236
|
+
def encrypt_block(block)
|
237
|
+
case @mode
|
238
|
+
when 'ECB'
|
239
|
+
_encrypt_block(block)
|
240
|
+
when 'CBC'
|
241
|
+
@iv = _encrypt_block(xor(block, @iv))
|
242
|
+
when 'OFB'
|
243
|
+
@iv = _encrypt_block(@iv)
|
244
|
+
xor(@iv, block)
|
245
|
+
when 'CFB'
|
246
|
+
@iv = xor(_encrypt_block(@iv), block)
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
def decrypt_block(block)
|
251
|
+
case @mode
|
252
|
+
when 'ECB'
|
253
|
+
_decrypt_block(block)
|
254
|
+
when 'CBC'
|
255
|
+
o = xor(_decrypt_block(block), @iv)
|
256
|
+
@iv = block
|
257
|
+
o
|
258
|
+
when 'OFB'
|
259
|
+
@iv = _encrypt_block(@iv)
|
260
|
+
xor(@iv, block)
|
261
|
+
when 'CFB'
|
262
|
+
o = xor(_encrypt_block(@iv), block)
|
263
|
+
@iv = block
|
264
|
+
o
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
def encrypt_blocks(buffer)
|
269
|
+
raise "Bad block length" unless (buffer.length % 16).zero?
|
270
|
+
ct = ""
|
271
|
+
block = ""
|
272
|
+
buffer.each_byte do |char|
|
273
|
+
block << char
|
274
|
+
if block.length == 16
|
275
|
+
ct << encrypt_block(block)
|
276
|
+
block = ""
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
def decrypt_blocks(buffer)
|
282
|
+
raise "Bad block length" unless (buffer.length % 16).zero?
|
283
|
+
pt = ""
|
284
|
+
block = ""
|
285
|
+
buffer.each_byte do |char|
|
286
|
+
block << char
|
287
|
+
if block.length == 16
|
288
|
+
pt << decrypt_block(block)
|
289
|
+
block = ""
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
def encrypt_buffer(buffer)
|
295
|
+
ct = ""
|
296
|
+
block = ""
|
297
|
+
buffer.each_byte do |char|
|
298
|
+
block << char
|
299
|
+
if block.length == 16
|
300
|
+
ct << encrypt_block(block)
|
301
|
+
block = ""
|
302
|
+
end
|
303
|
+
end
|
304
|
+
m = 16 - block.length % 16
|
305
|
+
ct << (m == 16 ? 0 : encrypt_block(block << m.chr * m))
|
306
|
+
end
|
307
|
+
|
308
|
+
def decrypt_buffer(buffer)
|
309
|
+
pt = ""
|
310
|
+
block = ""
|
311
|
+
buffer.each_byte do |char|
|
312
|
+
block << char
|
313
|
+
if block.length == 16
|
314
|
+
pt << decrypt_block(block)
|
315
|
+
block = ""
|
316
|
+
end
|
317
|
+
end
|
318
|
+
if block.length == 0
|
319
|
+
c = pt[-1]
|
320
|
+
c.chr * c == pt[-c..-1] ? pt[0..-(c+1)] : (raise "Bad Block Padding")
|
321
|
+
else
|
322
|
+
pt
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
def init(key_length, mode, key, iv = nil)
|
327
|
+
@nb = 4
|
328
|
+
@ek = []
|
329
|
+
@rk = []
|
330
|
+
@state = nil
|
331
|
+
@iv = "\000" * 16
|
332
|
+
@iv = iv if iv
|
333
|
+
case key_length
|
334
|
+
when 128
|
335
|
+
@nk = 4
|
336
|
+
@nr = 10
|
337
|
+
when 192
|
338
|
+
@nk = 6
|
339
|
+
@nr = 12
|
340
|
+
when 256
|
341
|
+
@nk = 8
|
342
|
+
@nr = 14
|
343
|
+
else
|
344
|
+
raise 'Bad Key length'
|
345
|
+
end
|
346
|
+
@kl = key_length
|
347
|
+
case mode
|
348
|
+
when 'ECB', 'CBC', 'OFB', 'CFB'
|
349
|
+
@mode = mode
|
350
|
+
else
|
351
|
+
raise 'Bad AES mode'
|
352
|
+
end
|
353
|
+
decryption_key_schedule(key)
|
354
|
+
end
|
355
|
+
|
356
|
+
def initialize(key_length, mode, key, iv = nil)
|
357
|
+
init(key_length, mode, key, iv)
|
358
|
+
end
|
359
|
+
|
360
|
+
end # AesAlg
|