ruby-aes-table2 1.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/ruby-aes.rb ADDED
@@ -0,0 +1,162 @@
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
+ ==Valid modes are:
6
+ * ECB (Electronic Code Book)
7
+ * CBC (Cipher Block Chaining)
8
+ * OFB (Output Feedback)
9
+ * CFB (Cipher Feedback)
10
+
11
+ ==Valid key length:
12
+ * 128 bits
13
+ * 192 bits
14
+ * 256 bits
15
+
16
+ ==API calls:
17
+ Default key_length: 128
18
+ Default mode: 'ECB'
19
+ Default IV: 16 null chars ("00" * 16 in hex format)
20
+ Default key: 16 null chars ("00" * 16 in hex format)
21
+ Default input text: "PLAINTEXT"
22
+
23
+ Aes.check_key(key_string, key_length)
24
+ Aes.check_iv(iv_string)
25
+ Aes.check_kl(key_length)
26
+ Aes.check_mode(mode)
27
+ Aes.init(key_length, mode, key, iv)
28
+ Aes.encrypt_block(key_length, mode, key, iv, block) # no padding
29
+ Aes.decrypt_block(key_length, mode, key, iv, block) # no padding
30
+ Aes.encrypt_buffer(key_length, mode, key, iv, block) # padding
31
+ Aes.decrypt_buffer(key_length, mode, key, iv, block) # padding
32
+ Aes.encrypt_stream(key_length, mode, key, iv, sin, sout)
33
+ Aes.decrypt_stream(key_length, mode, key, iv, sin, sout)
34
+ Aes.bs() # block size for read operations (stream)
35
+ Aes.bs=(bs)
36
+ =end
37
+
38
+ module Aes
39
+
40
+ require 'ruby-aes/aes_alg'
41
+
42
+ @@aes = nil
43
+ @@bs = 4096
44
+
45
+ def Aes.bs(); return @@bs end
46
+ def Aes.bs=(bs); @@bs = bs.to_i; @@bs==0 ? 4096 : @@bs = @@bs - @@bs%16 end
47
+
48
+ def Aes.check_key(key_string, kl = 128)
49
+ kl = Aes.check_kl(kl)
50
+ k = key_string.length
51
+ raise "Bad key string or bad key length" if (k != kl/8) && (k != kl/4)
52
+ hex = (key_string =~ /[a-f0-9A-F]{#{k}}/) == 0 && (k == kl/4)
53
+ bin = ! hex
54
+ if ! (([32, 48, 64].include?(k) && hex) ||
55
+ ([16, 24, 32].include?(k) && bin))
56
+ raise "Bad key string"
57
+ end
58
+ hex ? [key_string].pack("H*") : key_string
59
+ end
60
+
61
+ def Aes.check_iv(iv_string)
62
+ k = iv_string.length
63
+ hex = (iv_string =~ /[a-f0-9A-F]{#{k}}/) == 0
64
+ bin = ! hex
65
+ if k == 32 && hex
66
+ return [iv_string].pack("H*")
67
+ elsif k == 16 && bin
68
+ return iv_string
69
+ else
70
+ raise "Bad IV string"
71
+ end
72
+ end
73
+
74
+ def Aes.check_mode (mode)
75
+ case mode
76
+ when 'ECB', 'CBC', 'OFB', 'CFB'
77
+ else raise "Bad cipher mode"
78
+ end
79
+ mode
80
+ end
81
+
82
+ def Aes.check_kl(key_length)
83
+ case key_length
84
+ when 128, 192, 256
85
+ else raise "Bad key length"
86
+ end
87
+ key_length
88
+ end
89
+
90
+ def Aes.init(keyl, mode, key, iv)
91
+ unless @@aes
92
+ @@aes = AesAlg.new(Aes.check_kl(keyl), Aes.check_mode(mode),
93
+ Aes.check_key(key, keyl), iv ? Aes.check_iv(iv) : nil)
94
+ else
95
+ @@aes.init(Aes.check_kl(keyl), Aes.check_mode(mode),
96
+ Aes.check_key(key, keyl), iv ? Aes.check_iv(iv) : nil)
97
+ end
98
+ end
99
+
100
+ def Aes.encrypt_block(keyl, mode, key, iv, block = "DEFAULT PLAINTXT")
101
+ raise "Bad Block size" if block.length < 16 || block.length > 16
102
+ Aes.init(keyl, mode, key, iv)
103
+ @@aes.encrypt_block(block)
104
+ end
105
+
106
+ def Aes.decrypt_block(keyl, mode, key, iv, block = "DEFAULT PLAINTXT")
107
+ Aes.init(keyl, mode, key, iv)
108
+ @@aes.decrypt_block(block)
109
+ end
110
+
111
+ def Aes.encrypt_buffer(keyl, mode, key, iv, buffer = "PLAINTEXT")
112
+ Aes.init(keyl, mode, key, iv)
113
+ @@aes.encrypt_buffer(buffer)
114
+ end
115
+
116
+ def Aes.decrypt_buffer(keyl, mode, key, iv, buffer = "DEFAULT PLAINTXT")
117
+ raise "Bad Block size" if buffer.length < 16
118
+ Aes.init(keyl, mode, key, iv)
119
+ @@aes.decrypt_buffer(buffer)
120
+ end
121
+
122
+ def Aes.encrypt_stream(keyl, mode, key, iv, sin = STDIN, sout = STDOUT)
123
+ Aes.init(keyl, mode, key, iv)
124
+ case sout
125
+ when String, Array, IO
126
+ else
127
+ raise "Bad output stream (String, Array, IO)"
128
+ end
129
+ case sin
130
+ when String
131
+ sout << @@aes.encrypt_buffer(sin)
132
+ when IO
133
+ while buf = sin.read(@@bs)
134
+ sout << ((buf.length % 16).zero? ? @@aes.encrypt_blocks(buf) :
135
+ @@aes.encrypt_buffer(buf))
136
+ end
137
+ else
138
+ raise "Bad input stream (String, IO)"
139
+ end
140
+ end
141
+
142
+ def Aes.decrypt_stream(keyl, mode, key, iv, sin = STDIN, sout = STDOUT)
143
+ Aes.init(keyl, mode, key, iv)
144
+ case sout
145
+ when String, Array, IO
146
+ else
147
+ raise "Bad output stream (String, Array, IO)"
148
+ end
149
+ case sin
150
+ when String
151
+ sout << @@aes.decrypt_buffer(sin)
152
+ when IO
153
+ while buf = sin.read(@@bs)
154
+ sout << (sin.eof? ? @@aes.decrypt_buffer(buf) :
155
+ @@aes.decrypt_blocks(buf))
156
+ end
157
+ else
158
+ raise "Bad input stream (String, IO)"
159
+ end
160
+ end
161
+
162
+ end # end Aes
@@ -0,0 +1,372 @@
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
+
11
+ Added:
12
+ Table look up improvements
13
+ =end
14
+
15
+ require 'ruby-aes/aes_cons'
16
+
17
+ class AesAlg
18
+ include AesCons
19
+
20
+ def encryption_key_schedule(key)
21
+ i = 0
22
+ @ek = []
23
+ @ek[0] = key[0] << 24 | key[1] << 16 | key[2] << 8 | key[3]
24
+ @ek[1] = key[4] << 24 | key[5] << 16 | key[6] << 8 | key[7]
25
+ @ek[2] = key[8] << 24 | key[9] << 16 | key[10] << 8 | key[11]
26
+ @ek[3] = key[12] << 24 | key[13] << 16 | key[14] << 8 | key[15]
27
+ if @kl == 128
28
+ j = 0
29
+ loop do
30
+ temp = @ek[3+j]
31
+ @ek[4+j] = @ek[0+j] ^
32
+ (S3[(temp >> 16) & 0xff]) ^
33
+ (S2[(temp >> 8) & 0xff]) ^
34
+ (S1[(temp) & 0xff]) ^
35
+ (S0[(temp >> 24)]) ^ RCON[i]
36
+ @ek[5+j] = @ek[1+j] ^ @ek[4+j]
37
+ @ek[6+j] = @ek[2+j] ^ @ek[5+j]
38
+ @ek[7+j] = @ek[3+j] ^ @ek[6+j]
39
+ i += 1
40
+ return if (i == 10)
41
+ j += 4
42
+ end
43
+ end
44
+ @ek[4] = key[16] << 24 | key[17] << 16 | key[18] << 8 | key[19]
45
+ @ek[5] = key[20] << 24 | key[21] << 16 | key[22] << 8 | key[23]
46
+ if (@kl == 192)
47
+ j = 0
48
+ loop do
49
+ temp = @ek[ 5+j]
50
+ @ek[ 6+j] = @ek[ 0+j] ^
51
+ (S3[(temp >> 16) & 0xff]) ^
52
+ (S2[(temp >> 8) & 0xff]) ^
53
+ (S1[(temp) & 0xff]) ^
54
+ (S0[(temp >> 24)]) ^ RCON[i]
55
+ @ek[ 7+j] = @ek[ 1+j] ^ @ek[ 6+j]
56
+ @ek[ 8+j] = @ek[ 2+j] ^ @ek[ 7+j]
57
+ @ek[ 9+j] = @ek[ 3+j] ^ @ek[ 8+j]
58
+ i += 1
59
+ return if (i == 8)
60
+ @ek[10+j] = @ek[ 4+j] ^ @ek[ 9+j]
61
+ @ek[11+j] = @ek[ 5+j] ^ @ek[10+j]
62
+ j += 6
63
+ end
64
+ end
65
+ @ek[6] = key[24] << 24 | key[25] << 16 | key[26] << 8 | key[27]
66
+ @ek[7] = key[28] << 24 | key[29] << 16 | key[30] << 8 | key[31]
67
+ if (@kl == 256)
68
+ j = 0
69
+ loop do
70
+ temp = @ek[ 7+j]
71
+ @ek[ 8+j] = @ek[ 0+j] ^
72
+ (S3[(temp >> 16) & 0xff]) ^
73
+ (S2[(temp >> 8) & 0xff]) ^
74
+ (S1[(temp) & 0xff]) ^
75
+ (S0[(temp >> 24)]) ^ RCON[i]
76
+ @ek[ 9+j] = @ek[ 1+j] ^ @ek[ 8+j]
77
+ @ek[10+j] = @ek[ 2+j] ^ @ek[ 9+j]
78
+ @ek[11+j] = @ek[ 3+j] ^ @ek[10+j]
79
+ i += 1
80
+ return if (i == 7)
81
+ temp = @ek[11+j]
82
+ @ek[12+j] = @ek[ 4+j] ^
83
+ (S3[(temp >> 24)]) ^
84
+ (S2[(temp >> 16) & 0xff]) ^
85
+ (S1[(temp >> 8) & 0xff]) ^
86
+ (S0[(temp) & 0xff])
87
+ @ek[13+j] = @ek[ 5+j] ^ @ek[12+j]
88
+ @ek[14+j] = @ek[ 6+j] ^ @ek[13+j]
89
+ @ek[15+j] = @ek[ 7+j] ^ @ek[14+j]
90
+ j += 8
91
+ end
92
+ end
93
+ end
94
+ protected :encryption_key_schedule
95
+
96
+ def decryption_key_schedule(key)
97
+ # expand the cipher key:
98
+ encryption_key_schedule(key)
99
+ @dk = @ek.dup
100
+ # invert the order of the round keys:
101
+ j = 4 * @nr
102
+ i = 0
103
+ loop do
104
+ break if i >= j
105
+ temp = @dk[i]
106
+ @dk[i] = @dk[j]
107
+ @dk[j] = temp
108
+ temp = @dk[i + 1]
109
+ @dk[i + 1] = @dk[j + 1]
110
+ @dk[j + 1] = temp
111
+ temp = @dk[i + 2]
112
+ @dk[i + 2] = @dk[j + 2]
113
+ @dk[j + 2] = temp
114
+ temp = @dk[i + 3]
115
+ @dk[i + 3] = @dk[j + 3]
116
+ @dk[j + 3] = temp
117
+ i += 4
118
+ j -= 4
119
+ end
120
+ # apply the inverse MixColumn transform
121
+ # to all round keys but the first and the last:
122
+ j = 0
123
+ 1.upto(@nr-1) do |i|
124
+ j += 4
125
+ w0= @dk[j]
126
+ w1 = @dk[j+1]
127
+ w2 = @dk[j+2]
128
+ w3 = @dk[j+3]
129
+ @dk[0+j] =
130
+ Td0[S0[(w0 >> 24)] ]^
131
+ Td1[S0[(w0 >> 16) & 0xff] ] ^
132
+ Td2[S0[(w0 >> 8) & 0xff] ] ^
133
+ Td3[S0[(w0) & 0xff] ]
134
+ @dk[1+j] =
135
+ Td0[S0[(w1 >> 24)] ] ^
136
+ Td1[S0[(w1 >> 16) & 0xff] ] ^
137
+ Td2[S0[(w1 >> 8) & 0xff] ] ^
138
+ Td3[S0[(w1) & 0xff] ]
139
+ @dk[2+j] =
140
+ Td0[S0[(w2 >> 24)] ] ^
141
+ Td1[S0[(w2 >> 16) & 0xff] ] ^
142
+ Td2[S0[(w2 >> 8) & 0xff] ] ^
143
+ Td3[S0[(w2) & 0xff] ]
144
+ @dk[3+j] =
145
+ Td0[S0[(w3 >> 24)] ] ^
146
+ Td1[S0[(w3 >> 16) & 0xff] ] ^
147
+ Td2[S0[(w3 >> 8) & 0xff] ] ^
148
+ Td3[S0[(w3) & 0xff] ]
149
+ end
150
+ end
151
+ protected :decryption_key_schedule
152
+
153
+ def _encrypt_block(pt)
154
+ t0 = t1 = t2 = t3 = nil
155
+ # map byte array block to cipher state and add initial round key:
156
+ s0 = (pt[ 0] << 24 | pt[ 1] << 16 | pt[ 2] << 8 | pt[ 3]) ^ @ek[0]
157
+ s1 = (pt[ 4] << 24 | pt[ 5] << 16 | pt[ 6] << 8 | pt[ 7]) ^ @ek[1]
158
+ s2 = (pt[ 8] << 24 | pt[ 9] << 16 | pt[10] << 8 | pt[11]) ^ @ek[2]
159
+ s3 = (pt[12] << 24 | pt[13] << 16 | pt[14] << 8 | pt[15]) ^ @ek[3]
160
+ r = @nr >> 1
161
+ j = 0
162
+ loop {
163
+ t0 = Te0[(s0 >> 24) ] ^ Te1[(s1 >> 16) & 0xff] ^
164
+ Te2[(s2 >> 8) & 0xff] ^ Te3[(s3 ) & 0xff] ^ @ek[4+j]
165
+ t1 = Te0[(s1 >> 24) ] ^ Te1[(s2 >> 16) & 0xff] ^
166
+ Te2[(s3 >> 8) & 0xff] ^ Te3[(s0 ) & 0xff] ^ @ek[5+j]
167
+ t2 = Te0[(s2 >> 24) ] ^ Te1[(s3 >> 16) & 0xff] ^
168
+ Te2[(s0 >> 8) & 0xff] ^ Te3[(s1 ) & 0xff] ^ @ek[6+j]
169
+ t3 = Te0[(s3 >> 24) ] ^ Te1[(s0 >> 16) & 0xff] ^
170
+ Te2[(s1 >> 8) & 0xff] ^ Te3[(s2 ) & 0xff] ^ @ek[7+j]
171
+ j += 8
172
+ r -= 1
173
+ break if r == 0
174
+ s0 = Te0[(t0 >> 24) ] ^ Te1[(t1 >> 16) & 0xff] ^
175
+ Te2[(t2 >> 8) & 0xff] ^ Te3[(t3 ) & 0xff] ^ @ek[0+j]
176
+ s1 = Te0[(t1 >> 24) ] ^ Te1[(t2 >> 16) & 0xff] ^
177
+ Te2[(t3 >> 8) & 0xff] ^ Te3[(t0 ) & 0xff] ^ @ek[1+j]
178
+ s2 = Te0[(t2 >> 24) ] ^ Te1[(t3 >> 16) & 0xff] ^
179
+ Te2[(t0 >> 8) & 0xff] ^ Te3[(t1 ) & 0xff] ^ @ek[2+j]
180
+ s3 = Te0[(t3 >> 24) ] ^ Te1[(t0 >> 16) & 0xff] ^
181
+ Te2[(t1 >> 8) & 0xff] ^ Te3[(t2 ) & 0xff] ^ @ek[3+j]
182
+ }
183
+ # apply last round and map cipher state to byte array block:
184
+ s0 = (S3[(t0>>24)]) ^ (S2[(t1>>16)&0xff]) ^
185
+ (S1[(t2>>8)&0xff]) ^ (S0[(t3)&0xff]) ^ @ek[0+j]
186
+ s1 = (S3[(t1>>24)]) ^ (S2[(t2>>16)&0xff]) ^
187
+ (S1[(t3>>8)&0xff]) ^ (S0[(t0)&0xff]) ^ @ek[1+j]
188
+ s2 = (S3[(t2>>24)]) ^ (S2[(t3>>16)&0xff]) ^
189
+ (S1[(t0>>8)&0xff]) ^ (S0[(t1)&0xff]) ^ @ek[2+j]
190
+ s3 = (S3[(t3>>24)]) ^ (S2[(t0>>16)&0xff]) ^
191
+ (S1[(t1>>8)&0xff]) ^ (S0[(t2)&0xff]) ^ @ek[3+j]
192
+ [("%08x%08x%08x%08x" % [s0, s1, s2, s3])].pack("H*")
193
+ end
194
+ protected :_encrypt_block
195
+
196
+ def _decrypt_block(ct)
197
+ t0 = t1 = t2 = t3 = nil
198
+ # map byte array block to cipher state and add initial round key:
199
+ s0 = (ct[ 0] << 24 | ct[ 1] << 16 | ct[ 2] << 8 | ct[ 3]) ^ @dk[0]
200
+ s1 = (ct[ 4] << 24 | ct[ 5] << 16 | ct[ 6] << 8 | ct[ 7]) ^ @dk[1]
201
+ s2 = (ct[ 8] << 24 | ct[ 9] << 16 | ct[10] << 8 | ct[11]) ^ @dk[2]
202
+ s3 = (ct[12] << 24 | ct[13] << 16 | ct[14] << 8 | ct[15]) ^ @dk[3]
203
+ r = @nr >> 1
204
+ j = 0
205
+ loop {
206
+ t0 = Td0[(s0 >> 24) ] ^ Td1[(s3 >> 16) & 0xff] ^
207
+ Td2[(s2 >> 8) & 0xff] ^ Td3[(s1 ) & 0xff] ^ @dk[4+j]
208
+ t1 = Td0[(s1 >> 24) ] ^ Td1[(s0 >> 16) & 0xff] ^
209
+ Td2[(s3 >> 8) & 0xff] ^ Td3[(s2 ) & 0xff] ^ @dk[5+j]
210
+ t2 = Td0[(s2 >> 24) ] ^ Td1[(s1 >> 16) & 0xff] ^
211
+ Td2[(s0 >> 8) & 0xff] ^ Td3[(s3 ) & 0xff] ^ @dk[6+j]
212
+ t3 = Td0[(s3 >> 24) ] ^ Td1[(s2 >> 16) & 0xff] ^
213
+ Td2[(s1 >> 8) & 0xff] ^ Td3[(s0 ) & 0xff] ^ @dk[7+j]
214
+ j += 8
215
+ r -= 1
216
+ break if r == 0
217
+ s0 = Td0[(t0 >> 24) ] ^ Td1[(t3 >> 16) & 0xff] ^
218
+ Td2[(t2 >> 8) & 0xff] ^ Td3[(t1 ) & 0xff] ^ @dk[0+j]
219
+ s1 = Td0[(t1 >> 24) ] ^ Td1[(t0 >> 16) & 0xff] ^
220
+ Td2[(t3 >> 8) & 0xff] ^ Td3[(t2 ) & 0xff] ^ @dk[1+j]
221
+ s2 = Td0[(t2 >> 24) ] ^ Td1[(t1 >> 16) & 0xff] ^
222
+ Td2[(t0 >> 8) & 0xff] ^ Td3[(t3 ) & 0xff] ^ @dk[2+j]
223
+ s3 = Td0[(t3 >> 24) ] ^ Td1[(t2 >> 16) & 0xff] ^
224
+ Td2[(t1 >> 8) & 0xff] ^ Td3[(t0 ) & 0xff] ^ @dk[3+j]
225
+ }
226
+ # apply last round and map cipher state to byte array block:
227
+ s0 = (Si3[(t0>>24)]) ^ (Si2[(t3>>16)&0xff]) ^
228
+ (Si1[(t2>>8)&0xff]) ^ (Si0[(t1)&0xff]) ^ @dk[0+j]
229
+ s1 = (Si3[(t1>>24)]) ^ (Si2[(t0>>16)&0xff]) ^
230
+ (Si1[(t3>>8)&0xff]) ^ (Si0[(t2)&0xff]) ^ @dk[1+j]
231
+ s2 = (Si3[(t2>>24)]) ^ (Si2[(t1>>16)&0xff]) ^
232
+ (Si1[(t0>>8)&0xff]) ^ (Si0[(t3)&0xff]) ^ @dk[2+j]
233
+ s3 = (Si3[(t3>>24)]) ^ (Si2[(t2>>16)&0xff]) ^
234
+ (Si1[(t1>>8)&0xff]) ^ (Si0[(t0)&0xff]) ^ @dk[3+j]
235
+ [("%08x%08x%08x%08x" % [s0, s1, s2, s3])].pack("H*")
236
+ end
237
+ protected :_decrypt_block
238
+
239
+ def xor(a,b)
240
+ c = ""
241
+ 16.times do |i|
242
+ c << (a[i] ^ b[i]).chr
243
+ end
244
+ c
245
+ end
246
+ protected :xor
247
+
248
+ def encrypt_block(block)
249
+ case @mode
250
+ when 'ECB'
251
+ _encrypt_block(block)
252
+ when 'CBC'
253
+ @iv = _encrypt_block(xor(block, @iv))
254
+ when 'OFB'
255
+ @iv = _encrypt_block(@iv)
256
+ xor(@iv, block)
257
+ when 'CFB'
258
+ @iv = xor(_encrypt_block(@iv), block)
259
+ end
260
+ end
261
+
262
+ def decrypt_block(block)
263
+ case @mode
264
+ when 'ECB'
265
+ _decrypt_block(block)
266
+ when 'CBC'
267
+ o = xor(_decrypt_block(block), @iv)
268
+ @iv = block
269
+ o
270
+ when 'OFB'
271
+ @iv = _encrypt_block(@iv)
272
+ xor(@iv, block)
273
+ when 'CFB'
274
+ o = xor(_encrypt_block(@iv), block)
275
+ @iv = block
276
+ o
277
+ end
278
+ end
279
+
280
+ def encrypt_blocks(buffer)
281
+ raise "Bad block length" unless (buffer.length % 16).zero?
282
+ ct = ""
283
+ block = ""
284
+ buffer.each_byte do |char|
285
+ block << char
286
+ if block.length == 16
287
+ ct << encrypt_block(block)
288
+ block = ""
289
+ end
290
+ end
291
+ end
292
+
293
+ def decrypt_blocks(buffer)
294
+ raise "Bad block length" unless (buffer.length % 16).zero?
295
+ pt = ""
296
+ block = ""
297
+ buffer.each_byte do |char|
298
+ block << char
299
+ if block.length == 16
300
+ pt << decrypt_block(block)
301
+ block = ""
302
+ end
303
+ end
304
+ end
305
+
306
+ def encrypt_buffer(buffer)
307
+ ct = ""
308
+ block = ""
309
+ buffer.each_byte do |char|
310
+ block << char
311
+ if block.length == 16
312
+ ct << encrypt_block(block)
313
+ block = ""
314
+ end
315
+ end
316
+ m = 16 - block.length % 16
317
+ ct << (m == 16 ? 0 : encrypt_block(block << m.chr * m))
318
+ end
319
+
320
+ def decrypt_buffer(buffer)
321
+ pt = ""
322
+ block = ""
323
+ buffer.each_byte do |char|
324
+ block << char
325
+ if block.length == 16
326
+ pt << decrypt_block(block)
327
+ block = ""
328
+ end
329
+ end
330
+ if block.length == 0
331
+ c = pt[-1]
332
+ c.chr * c == pt[-c..-1] ? pt[0..-(c+1)] : (raise "Bad Block Padding")
333
+ else
334
+ pt
335
+ end
336
+ end
337
+
338
+ def init(key_length, mode, key, iv = nil)
339
+ @nb = 4
340
+ @ek = []
341
+ @dk = []
342
+ @state = nil
343
+ @iv = "\000" * 16
344
+ @iv = iv if iv
345
+ case key_length
346
+ when 128
347
+ @nk = 4
348
+ @nr = 10
349
+ when 192
350
+ @nk = 6
351
+ @nr = 12
352
+ when 256
353
+ @nk = 8
354
+ @nr = 14
355
+ else
356
+ raise 'Bad Key length'
357
+ end
358
+ @kl = key_length
359
+ case mode
360
+ when 'ECB', 'CBC', 'OFB', 'CFB'
361
+ @mode = mode
362
+ else
363
+ raise 'Bad AES mode'
364
+ end
365
+ decryption_key_schedule(key)
366
+ end
367
+
368
+ def initialize(key_length, mode, key, iv = nil)
369
+ init(key_length, mode, key, iv)
370
+ end
371
+
372
+ end # AesAlg