ruby-aes-table2 1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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