ruby-aes-cext 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.
@@ -0,0 +1,812 @@
1
+ #include "ruby.h"
2
+
3
+ /*
4
+ This file is a part of ruby-aes <http://rubyforge.org/projects/ruby-aes>
5
+ Written by Alex Boussinet <alex.boussinet@gmail.com>
6
+
7
+ This version is derived from the Optimised ANSI C code
8
+ Authors of C version:
9
+ Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
10
+ Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
11
+ Paulo Barreto <paulo.barreto@terra.com.br>
12
+ Loop unroll optimization
13
+
14
+ Added:
15
+ Table look up improvements based on "Table Unroll Optimized 2" variation
16
+ */
17
+
18
+ #ifdef DEBUG
19
+ #define TRACE() fprintf(stderr, "> %s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__)
20
+ #else
21
+ #define TRACE()
22
+ #endif
23
+
24
+ #define MODE_ECB 0
25
+ #define MODE_CBC 1
26
+ #define MODE_CFB 2
27
+ #define MODE_OFB 3
28
+
29
+ typedef unsigned int uint;
30
+ typedef unsigned char uchar;
31
+
32
+ #include "aes_cons.h"
33
+
34
+ #define SWAP(n) \
35
+ (((n & 0x000000ff) << 24) | ((n & 0x0000ff00) << 8) | \
36
+ ((n & 0x00ff0000) >> 8) | ((n & 0xff000000) >> 24))
37
+
38
+ typedef struct {
39
+ uchar *state;
40
+ uchar *state2;
41
+ uchar *iv;
42
+ uchar *key;
43
+ uint *ek; /* encryption key */
44
+ uint *dk; /* decryption key */
45
+ int mode;
46
+ int kl;
47
+ int nb;
48
+ int nr;
49
+ int nk;
50
+ } AES;
51
+
52
+ static VALUE rb_cAes;
53
+
54
+ #define BLOCK_SIZE 16
55
+
56
+ #define FREE(ptr) freeset((void**)&ptr)
57
+ void
58
+ freeset(void **ptr)
59
+ {
60
+ free(*ptr);
61
+ *ptr = NULL;
62
+ }
63
+
64
+ void
65
+ aes_encrypt(AES *data, uchar *pt, uchar *output)
66
+ {
67
+ int j;
68
+
69
+ /* map byte array block to cipher state and add initial round key: */
70
+ uint s0 = (pt[ 0] << 24 | pt[ 1] << 16 | pt[ 2] << 8 | pt[ 3]) ^ data->ek[0];
71
+ uint s1 = (pt[ 4] << 24 | pt[ 5] << 16 | pt[ 6] << 8 | pt[ 7]) ^ data->ek[1];
72
+ uint s2 = (pt[ 8] << 24 | pt[ 9] << 16 | pt[10] << 8 | pt[11]) ^ data->ek[2];
73
+ uint s3 = (pt[12] << 24 | pt[13] << 16 | pt[14] << 8 | pt[15]) ^ data->ek[3];
74
+ /* round 1: */
75
+ uint t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^
76
+ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ data->ek[ 4];
77
+ uint t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^
78
+ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ data->ek[ 5];
79
+ uint t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^
80
+ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ data->ek[ 6];
81
+ uint t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^
82
+ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ data->ek[ 7];
83
+ /* round 2: */
84
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^
85
+ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ data->ek[ 8];
86
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^
87
+ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ data->ek[ 9];
88
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^
89
+ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ data->ek[10];
90
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^
91
+ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ data->ek[11];
92
+ /* round 3: */
93
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^
94
+ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ data->ek[12];
95
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^
96
+ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ data->ek[13];
97
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^
98
+ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ data->ek[14];
99
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^
100
+ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ data->ek[15];
101
+ /* round 4: */
102
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^
103
+ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ data->ek[16];
104
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^
105
+ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ data->ek[17];
106
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^
107
+ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ data->ek[18];
108
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^
109
+ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ data->ek[19];
110
+ /* round 5: */
111
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^
112
+ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ data->ek[20];
113
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^
114
+ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ data->ek[21];
115
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^
116
+ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ data->ek[22];
117
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^
118
+ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ data->ek[23];
119
+ /* round 6: */
120
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^
121
+ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ data->ek[24];
122
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^
123
+ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ data->ek[25];
124
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^
125
+ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ data->ek[26];
126
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^
127
+ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ data->ek[27];
128
+ /* round 7: */
129
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^
130
+ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ data->ek[28];
131
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^
132
+ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ data->ek[29];
133
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^
134
+ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ data->ek[30];
135
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^
136
+ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ data->ek[31];
137
+ /* round 8: */
138
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^
139
+ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ data->ek[32];
140
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^
141
+ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ data->ek[33];
142
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^
143
+ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ data->ek[34];
144
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^
145
+ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ data->ek[35];
146
+ /* round 9: */
147
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^
148
+ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ data->ek[36];
149
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^
150
+ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ data->ek[37];
151
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^
152
+ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ data->ek[38];
153
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^
154
+ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ data->ek[39];
155
+ if (data->nr > 10) {
156
+ /* round 10: */
157
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^
158
+ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ data->ek[40];
159
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^
160
+ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ data->ek[41];
161
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^
162
+ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ data->ek[42];
163
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^
164
+ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ data->ek[43];
165
+ /* round 11: */
166
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^
167
+ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ data->ek[44];
168
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^
169
+ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ data->ek[45];
170
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^
171
+ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ data->ek[46];
172
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^
173
+ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ data->ek[47];
174
+ if (data->nr > 12) {
175
+ /* round 12: */
176
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^
177
+ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ data->ek[48];
178
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^
179
+ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ data->ek[49];
180
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^
181
+ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ data->ek[50];
182
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^
183
+ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ data->ek[51];
184
+ /* round 13: */
185
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^
186
+ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ data->ek[52];
187
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^
188
+ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ data->ek[53];
189
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^
190
+ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ data->ek[54];
191
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^
192
+ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ data->ek[55];
193
+ }
194
+ }
195
+ j = data->nr << 2;
196
+ /* apply last round and map cipher state to byte array block: */
197
+ s0 =
198
+ (S3[(t0 >> 24)]) ^
199
+ (S2[(t1 >> 16) & 0xff]) ^
200
+ (S1[(t2 >> 8) & 0xff]) ^
201
+ (S0[(t3) & 0xff]) ^ data->ek[0+j];
202
+ s1 =
203
+ (S3[(t1 >> 24)]) ^
204
+ (S2[(t2 >> 16) & 0xff]) ^
205
+ (S1[(t3 >> 8) & 0xff]) ^
206
+ (S0[(t0) & 0xff]) ^ data->ek[1+j];
207
+ s2 =
208
+ (S3[(t2 >> 24)]) ^
209
+ (S2[(t3 >> 16) & 0xff]) ^
210
+ (S1[(t0 >> 8) & 0xff]) ^
211
+ (S0[(t1) & 0xff]) ^ data->ek[2+j];
212
+ s3 =
213
+ (S3[(t3 >> 24)]) ^
214
+ (S2[(t0 >> 16) & 0xff]) ^
215
+ (S1[(t1 >> 8) & 0xff]) ^
216
+ (S0[(t2) & 0xff]) ^ data->ek[3+j];
217
+
218
+ *(uint*)output = SWAP(s0);
219
+ *(uint*)&output[4] = SWAP(s1);
220
+ *(uint*)&output[8] = SWAP(s2);
221
+ *(uint*)&output[12] = SWAP(s3);
222
+ }
223
+
224
+ void
225
+ aes_decrypt(AES *data, uchar *ct, uchar *output)
226
+ {
227
+ int j;
228
+
229
+ /* map byte array block to cipher state and add initial round key: */
230
+ uint s0 = (ct[ 0] << 24 | ct[ 1] << 16 | ct[ 2] << 8 | ct[ 3]) ^ data->dk[0];
231
+ uint s1 = (ct[ 4] << 24 | ct[ 5] << 16 | ct[ 6] << 8 | ct[ 7]) ^ data->dk[1];
232
+ uint s2 = (ct[ 8] << 24 | ct[ 9] << 16 | ct[10] << 8 | ct[11]) ^ data->dk[2];
233
+ uint s3 = (ct[12] << 24 | ct[13] << 16 | ct[14] << 8 | ct[15]) ^ data->dk[3];
234
+ /* round 1: */
235
+ uint t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^
236
+ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ data->dk[ 4];
237
+ uint t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^
238
+ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ data->dk[ 5];
239
+ uint t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^
240
+ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ data->dk[ 6];
241
+ uint t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^
242
+ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ data->dk[ 7];
243
+ /* round 2: */
244
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^
245
+ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ data->dk[ 8];
246
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^
247
+ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ data->dk[ 9];
248
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^
249
+ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ data->dk[10];
250
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^
251
+ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ data->dk[11];
252
+ /* round 3: */
253
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^
254
+ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ data->dk[12];
255
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^
256
+ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ data->dk[13];
257
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^
258
+ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ data->dk[14];
259
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^
260
+ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ data->dk[15];
261
+ /* round 4: */
262
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^
263
+ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ data->dk[16];
264
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^
265
+ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ data->dk[17];
266
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^
267
+ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ data->dk[18];
268
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^
269
+ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ data->dk[19];
270
+ /* round 5: */
271
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^
272
+ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ data->dk[20];
273
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^
274
+ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ data->dk[21];
275
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^
276
+ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ data->dk[22];
277
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^
278
+ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ data->dk[23];
279
+ /* round 6: */
280
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^
281
+ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ data->dk[24];
282
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^
283
+ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ data->dk[25];
284
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^
285
+ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ data->dk[26];
286
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^
287
+ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ data->dk[27];
288
+ /* round 7: */
289
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^
290
+ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ data->dk[28];
291
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^
292
+ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ data->dk[29];
293
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^
294
+ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ data->dk[30];
295
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^
296
+ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ data->dk[31];
297
+ /* round 8: */
298
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^
299
+ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ data->dk[32];
300
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^
301
+ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ data->dk[33];
302
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^
303
+ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ data->dk[34];
304
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^
305
+ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ data->dk[35];
306
+ /* round 9: */
307
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^
308
+ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ data->dk[36];
309
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^
310
+ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ data->dk[37];
311
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^
312
+ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ data->dk[38];
313
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^
314
+ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ data->dk[39];
315
+ if (data->nr > 10) {
316
+ /* round 10: */
317
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^
318
+ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ data->dk[40];
319
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^
320
+ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ data->dk[41];
321
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^
322
+ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ data->dk[42];
323
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^
324
+ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ data->dk[43];
325
+ /* round 11: */
326
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^
327
+ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ data->dk[44];
328
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^
329
+ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ data->dk[45];
330
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^
331
+ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ data->dk[46];
332
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^
333
+ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ data->dk[47];
334
+ if (data->nr > 12) {
335
+ /* round 12: */
336
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^
337
+ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ data->dk[48];
338
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^
339
+ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ data->dk[49];
340
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^
341
+ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ data->dk[50];
342
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^
343
+ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ data->dk[51];
344
+ /* round 13: */
345
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^
346
+ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ data->dk[52];
347
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^
348
+ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ data->dk[53];
349
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^
350
+ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ data->dk[54];
351
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^
352
+ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ data->dk[55];
353
+ }
354
+ }
355
+ j = data->nr << 2;
356
+ /* apply last round and map cipher state to byte array block: */
357
+ s0 =
358
+ (Si3[(t0 >> 24)]) ^
359
+ (Si2[(t3 >> 16) & 0xff]) ^
360
+ (Si1[(t2 >> 8) & 0xff]) ^
361
+ (Si0[(t1) & 0xff]) ^ data->dk[0+j];
362
+ s1 =
363
+ (Si3[(t1 >> 24)]) ^
364
+ (Si2[(t0 >> 16) & 0xff]) ^
365
+ (Si1[(t3 >> 8) & 0xff]) ^
366
+ (Si0[(t2) & 0xff]) ^ data->dk[1+j];
367
+ s2 =
368
+ (Si3[(t2 >> 24)]) ^
369
+ (Si2[(t1 >> 16) & 0xff]) ^
370
+ (Si1[(t0 >> 8) & 0xff]) ^
371
+ (Si0[(t3) & 0xff]) ^ data->dk[2+j];
372
+ s3 =
373
+ (Si3[(t3 >> 24)]) ^
374
+ (Si2[(t2 >> 16) & 0xff]) ^
375
+ (Si1[(t1 >> 8) & 0xff]) ^
376
+ (Si0[(t0) & 0xff]) ^ data->dk[3+j];
377
+
378
+ *(uint*)output = SWAP(s0);
379
+ *(uint*)&output[4] = SWAP(s1);
380
+ *(uint*)&output[8] = SWAP(s2);
381
+ *(uint*)&output[12] = SWAP(s3);
382
+ }
383
+
384
+ void
385
+ xor(const uchar *a, uchar *b)
386
+ {
387
+ int i;
388
+
389
+ for (i = 0; i < BLOCK_SIZE; i++) b[i] = a[i] ^ b[i];
390
+ }
391
+
392
+ void
393
+ set_state(const uchar *block, uchar *buffer)
394
+ {
395
+ MEMCPY(buffer, block, uchar, BLOCK_SIZE);
396
+ }
397
+
398
+ uchar*
399
+ aes_encrypt_block(AES *data, const uchar *block)
400
+ {
401
+ uchar *state = data->state;
402
+
403
+ set_state(block, data->state);
404
+
405
+ switch (data->mode) {
406
+ case MODE_ECB:
407
+ aes_encrypt(data, data->state, data->state);
408
+ break;
409
+ case MODE_CBC:
410
+ xor(data->iv, data->state);
411
+ aes_encrypt(data, data->state, data->iv);
412
+ state = data->iv;
413
+ break;
414
+ case MODE_OFB:
415
+ aes_encrypt(data, data->iv, data->iv);
416
+ xor(data->iv, data->state);
417
+ break;
418
+ case MODE_CFB:
419
+ aes_encrypt(data, data->iv, data->iv);
420
+ xor(data->state, data->iv);
421
+ state = data->iv;
422
+ break;
423
+ }
424
+ return state;
425
+ }
426
+
427
+ uchar*
428
+ aes_decrypt_block(AES *data, const uchar *block)
429
+ {
430
+ uchar *state = data->state;
431
+
432
+ set_state(block, data->state);
433
+
434
+ switch (data->mode) {
435
+ case MODE_ECB:
436
+ aes_decrypt(data, data->state, data->state);
437
+ break;
438
+ case MODE_CBC:
439
+ aes_decrypt(data, data->state, data->state2);
440
+ xor(data->iv, data->state2);
441
+ set_state(block, data->iv);
442
+ state = data->state2;
443
+ break;
444
+ case MODE_OFB:
445
+ aes_encrypt(data, data->iv, data->iv);
446
+ xor(data->iv, data->state);
447
+ break;
448
+ case MODE_CFB:
449
+ aes_encrypt(data, data->iv, data->state2);
450
+ xor(data->state, data->state2);
451
+ set_state(block, data->iv);
452
+ state = data->state2;
453
+ break;
454
+ }
455
+ return state;
456
+ }
457
+
458
+ static VALUE
459
+ rb_aes_encrypt_block(VALUE self, VALUE block)
460
+ {
461
+ return rb_str_new(aes_encrypt_block(DATA_PTR(self), RSTRING(block)->ptr), BLOCK_SIZE);
462
+ }
463
+
464
+ static VALUE
465
+ rb_aes_decrypt_block(VALUE self, VALUE block)
466
+ {
467
+ return rb_str_new(aes_decrypt_block(DATA_PTR(self), RSTRING(block)->ptr), BLOCK_SIZE);
468
+ }
469
+
470
+ void
471
+ aes_encrypt_blocks(AES *data, int len, const char* ptr, VALUE ct)
472
+ {
473
+ if (len % BLOCK_SIZE) rb_raise(rb_eRuntimeError, "Bad block length");
474
+ for (; len >= BLOCK_SIZE; len -= BLOCK_SIZE, ptr += BLOCK_SIZE)
475
+ rb_str_cat(ct, aes_encrypt_block(data, ptr), BLOCK_SIZE);
476
+ }
477
+
478
+ void
479
+ aes_decrypt_blocks(AES *data, int len, const char* ptr, VALUE pt)
480
+ {
481
+ if (len % BLOCK_SIZE) rb_raise(rb_eRuntimeError, "Bad block length");
482
+ for (; len >= BLOCK_SIZE; len -= BLOCK_SIZE, ptr += BLOCK_SIZE)
483
+ rb_str_cat(pt, aes_decrypt_block(data, ptr), BLOCK_SIZE);
484
+ }
485
+
486
+ static VALUE
487
+ rb_aes_encrypt_blocks(VALUE self, VALUE buffer)
488
+ {
489
+ AES *data = DATA_PTR(self);
490
+ VALUE ct = rb_str_new("", 0);
491
+
492
+ aes_encrypt_blocks(data, RSTRING(buffer)->len, RSTRING(buffer)->ptr, ct);
493
+
494
+ return ct;
495
+ }
496
+
497
+ static VALUE
498
+ rb_aes_decrypt_blocks(VALUE self, VALUE buffer)
499
+ {
500
+ AES *data = DATA_PTR(self);
501
+ VALUE pt = rb_str_new("", 0);
502
+
503
+ aes_decrypt_blocks(data, RSTRING(buffer)->len, RSTRING(buffer)->ptr, pt);
504
+
505
+ return pt;
506
+ }
507
+
508
+ static VALUE
509
+ rb_aes_encrypt_buffer(VALUE self, VALUE buffer)
510
+ {
511
+ AES *data = DATA_PTR(self);
512
+ const char *ptr = RSTRING(buffer)->ptr;
513
+ int i, len = RSTRING(buffer)->len;
514
+ uchar pad, *buf;
515
+ VALUE ct = rb_str_new("", 0);
516
+
517
+ for (; len >= BLOCK_SIZE; len -= BLOCK_SIZE, ptr += BLOCK_SIZE)
518
+ rb_str_cat(ct, aes_encrypt_block(data, ptr), BLOCK_SIZE);
519
+ if (len > 0 && len < BLOCK_SIZE) {
520
+ pad = BLOCK_SIZE - len % BLOCK_SIZE;
521
+ buf = ALLOC_N(uchar, BLOCK_SIZE);
522
+ MEMCPY(buf, ptr, uchar, len);
523
+ for (i = len; i < BLOCK_SIZE; i++)
524
+ buf[i] = pad;
525
+ rb_str_cat(ct, aes_encrypt_block(data, buf), BLOCK_SIZE);
526
+ free(buf);
527
+ }/* else
528
+ rb_str_cat(ct, "\x0", 1);*/
529
+
530
+ return ct;
531
+ }
532
+
533
+ static VALUE
534
+ rb_aes_decrypt_buffer(VALUE self, VALUE buffer)
535
+ {
536
+ AES *data = DATA_PTR(self);
537
+ const char *ptr = RSTRING(buffer)->ptr;
538
+ int i, len = RSTRING(buffer)->len;
539
+ uchar pad;
540
+ VALUE pt = rb_str_new("", 0);
541
+
542
+ for (; len >= BLOCK_SIZE; len -= BLOCK_SIZE, ptr += BLOCK_SIZE)
543
+ rb_str_cat(pt, aes_decrypt_block(data, ptr), BLOCK_SIZE);
544
+ if (len == 0) {
545
+ i = RSTRING(pt)->len;
546
+ ptr = RSTRING(pt)->ptr + i - 1;
547
+ pad = *ptr;
548
+ if (pad < BLOCK_SIZE) {
549
+ for (; i > 0 && pad == *ptr; ptr--, i--, len++);
550
+ /*if (pad != len)
551
+ rb_raise(rb_eRuntimeError, "Bad Block Padding");*/
552
+ if (pad == len)
553
+ rb_str_resize(pt, i);
554
+ }
555
+ } else/* if (len != 1)*/
556
+ rb_raise(rb_eRuntimeError, "Bad Block Padding");
557
+ return pt;
558
+ }
559
+
560
+ void
561
+ encryption_key_schedule(AES *data, uchar *key)
562
+ {
563
+ int i = 0, j;
564
+ uint temp;
565
+
566
+ if (data->ek) FREE(data->ek);
567
+ data->ek = ALLOC_N(uint, 4 * (data->nr + 1));
568
+ MEMZERO(data->ek, uint, 4 * (data->nr + 1));
569
+
570
+ data->ek[0] = key[0] << 24 | key[1] << 16 | key[2] << 8 | key[3];
571
+ data->ek[1] = key[4] << 24 | key[5] << 16 | key[6] << 8 | key[7];
572
+ data->ek[2] = key[8] << 24 | key[9] << 16 | key[10] << 8 | key[11];
573
+ data->ek[3] = key[12] << 24 | key[13] << 16 | key[14] << 8 | key[15];
574
+ if (data->kl == 128) {
575
+ j = 0;
576
+ for (;;) {
577
+ temp = data->ek[3+j];
578
+ data->ek[4+j] = data->ek[0+j] ^
579
+ (S3[(temp >> 16) & 0xff]) ^
580
+ (S2[(temp >> 8) & 0xff]) ^
581
+ (S1[(temp) & 0xff]) ^
582
+ (S0[(temp >> 24)]) ^ RCON[i];
583
+ data->ek[5+j] = data->ek[1+j] ^ data->ek[4+j];
584
+ data->ek[6+j] = data->ek[2+j] ^ data->ek[5+j];
585
+ data->ek[7+j] = data->ek[3+j] ^ data->ek[6+j];
586
+ i += 1;
587
+ if (i == 10) return;
588
+ j += 4;
589
+ }
590
+ }
591
+ data->ek[4] = key[16] << 24 | key[17] << 16 | key[18] << 8 | key[19];
592
+ data->ek[5] = key[20] << 24 | key[21] << 16 | key[22] << 8 | key[23];
593
+ if (data->kl == 192) {
594
+ j = 0;
595
+ for (;;) {
596
+ temp = data->ek[ 5+j];
597
+ data->ek[ 6+j] = data->ek[ 0+j] ^
598
+ (S3[(temp >> 16) & 0xff]) ^
599
+ (S2[(temp >> 8) & 0xff]) ^
600
+ (S1[(temp) & 0xff]) ^
601
+ (S0[(temp >> 24)]) ^ RCON[i];
602
+ data->ek[ 7+j] = data->ek[ 1+j] ^ data->ek[ 6+j];
603
+ data->ek[ 8+j] = data->ek[ 2+j] ^ data->ek[ 7+j];
604
+ data->ek[ 9+j] = data->ek[ 3+j] ^ data->ek[ 8+j];
605
+ i += 1;
606
+ if (i == 8) return;
607
+ data->ek[10+j] = data->ek[ 4+j] ^ data->ek[ 9+j];
608
+ data->ek[11+j] = data->ek[ 5+j] ^ data->ek[10+j];
609
+ j += 6;
610
+ }
611
+ }
612
+ data->ek[6] = key[24] << 24 | key[25] << 16 | key[26] << 8 | key[27];
613
+ data->ek[7] = key[28] << 24 | key[29] << 16 | key[30] << 8 | key[31];
614
+ if (data->kl == 256) {
615
+ j = 0;
616
+ for (;;) {
617
+ temp = data->ek[ 7+j];
618
+ data->ek[ 8+j] = data->ek[ 0+j] ^
619
+ (S3[(temp >> 16) & 0xff]) ^
620
+ (S2[(temp >> 8) & 0xff]) ^
621
+ (S1[(temp) & 0xff]) ^
622
+ (S0[(temp >> 24)]) ^ RCON[i];
623
+ data->ek[ 9+j] = data->ek[ 1+j] ^ data->ek[ 8+j];
624
+ data->ek[10+j] = data->ek[ 2+j] ^ data->ek[ 9+j];
625
+ data->ek[11+j] = data->ek[ 3+j] ^ data->ek[10+j];
626
+ i += 1;
627
+ if (i == 7) return;
628
+ temp = data->ek[11+j];
629
+ data->ek[12+j] = data->ek[ 4+j] ^
630
+ (S3[(temp >> 24)]) ^
631
+ (S2[(temp >> 16) & 0xff]) ^
632
+ (S1[(temp >> 8) & 0xff]) ^
633
+ (S0[(temp) & 0xff]);
634
+ data->ek[13+j] = data->ek[ 5+j] ^ data->ek[12+j];
635
+ data->ek[14+j] = data->ek[ 6+j] ^ data->ek[13+j];
636
+ data->ek[15+j] = data->ek[ 7+j] ^ data->ek[14+j];
637
+ j += 8;
638
+ }
639
+ }
640
+ }
641
+
642
+ void
643
+ decryption_key_schedule(AES *data, uchar *key)
644
+ {
645
+ int i = 0, j = 4 * data->nr;
646
+ uint w0, w1, w2, w3, temp;
647
+
648
+ encryption_key_schedule(data, key);
649
+
650
+ if (data->dk) FREE(data->dk);
651
+ data->dk = ALLOC_N(uint, 4 * (data->nr + 1));
652
+ MEMCPY(data->dk, data->ek, uint, 4 * (data->nr + 1));
653
+
654
+ /* invert the order of the round keys:*/
655
+ for (;;) {
656
+ if (i >= j) break;
657
+ temp = data->dk[i ]; data->dk[i ] = data->dk[j ]; data->dk[j ] = temp;
658
+ temp = data->dk[i + 1]; data->dk[i + 1] = data->dk[j + 1]; data->dk[j + 1] = temp;
659
+ temp = data->dk[i + 2]; data->dk[i + 2] = data->dk[j + 2]; data->dk[j + 2] = temp;
660
+ temp = data->dk[i + 3]; data->dk[i + 3] = data->dk[j + 3]; data->dk[j + 3] = temp;
661
+ i += 4; j -= 4;
662
+ }
663
+ /* apply the inverse MixColumn transform*/
664
+ /* to all round keys but the first and the last:*/
665
+ j = 0;
666
+ for (i = 1; i < data->nr; i++) {
667
+ j += 4;
668
+ w0 = data->dk[j];
669
+ w1 = data->dk[j+1];
670
+ w2 = data->dk[j+2];
671
+ w3 = data->dk[j+3];
672
+ data->dk[0+j] =
673
+ Td0[S0[(w0 >> 24)] ] ^
674
+ Td1[S0[(w0 >> 16) & 0xff] ] ^
675
+ Td2[S0[(w0 >> 8) & 0xff] ] ^
676
+ Td3[S0[(w0) & 0xff] ];
677
+ data->dk[1+j] =
678
+ Td0[S0[(w1 >> 24)] ] ^
679
+ Td1[S0[(w1 >> 16) & 0xff] ] ^
680
+ Td2[S0[(w1 >> 8) & 0xff] ] ^
681
+ Td3[S0[(w1) & 0xff] ];
682
+ data->dk[2+j] =
683
+ Td0[S0[(w2 >> 24)] ] ^
684
+ Td1[S0[(w2 >> 16) & 0xff] ] ^
685
+ Td2[S0[(w2 >> 8) & 0xff] ] ^
686
+ Td3[S0[(w2) & 0xff] ];
687
+ data->dk[3+j] =
688
+ Td0[S0[(w3 >> 24)] ] ^
689
+ Td1[S0[(w3 >> 16) & 0xff] ] ^
690
+ Td2[S0[(w3 >> 8) & 0xff] ] ^
691
+ Td3[S0[(w3) & 0xff] ];
692
+ }
693
+ }
694
+
695
+ static VALUE
696
+ rb_aes_c_extension()
697
+ {
698
+ return Qtrue;
699
+ }
700
+
701
+ static VALUE
702
+ rb_aes_init(VALUE self, VALUE kl, VALUE mode, VALUE key, VALUE iv)
703
+ {
704
+ AES *data = DATA_PTR(self);
705
+
706
+ data->kl = FIX2INT(kl);
707
+
708
+ if (data->kl == 128) {
709
+ data->nk = 4;
710
+ data->nr = 10;
711
+ } else if (data->kl == 192) {
712
+ data->nk = 6;
713
+ data->nr = 12;
714
+ } else if (data->kl == 256) {
715
+ data->nk = 8;
716
+ data->nr = 14;
717
+ } else {
718
+ rb_raise(rb_eArgError, "Bad Key Length");
719
+ }
720
+ data->nb = 4;
721
+
722
+ char *mode_str = RSTRING(mode)->ptr;
723
+ if (!strncmp(mode_str, "ECB", 3)) data->mode = MODE_ECB;
724
+ else if (!strncmp(mode_str, "CBC", 3)) data->mode = MODE_CBC;
725
+ else if (!strncmp(mode_str, "CFB", 3)) data->mode = MODE_CFB;
726
+ else if (!strncmp(mode_str, "OFB", 3)) data->mode = MODE_OFB;
727
+ else rb_raise(rb_eArgError, "Bad AES mode");
728
+
729
+ if (data->key) FREE(data->key);
730
+ data->key = ALLOC_N(uchar, 32);
731
+ MEMCPY(data->key, RSTRING(key)->ptr, uchar, RSTRING(key)->len > 32 ? 32 : RSTRING(key)->len);
732
+
733
+ if (data->iv) FREE(data->iv);
734
+ if (NIL_P(iv)) {
735
+ data->iv = NULL;
736
+ } else {
737
+ data->iv = ALLOC_N(uchar, BLOCK_SIZE);
738
+ MEMCPY(data->iv, RSTRING(iv)->ptr, uchar, BLOCK_SIZE);
739
+ }
740
+
741
+ decryption_key_schedule(data, data->key);
742
+
743
+ return self;
744
+ }
745
+
746
+ static void
747
+ rb_aes_mark(AES *data)
748
+ {
749
+ }
750
+
751
+ static void
752
+ rb_aes_free(AES *data)
753
+ {
754
+ if (data) {
755
+ if (data->state) FREE(data->state);
756
+ if (data->state2) FREE(data->state2);
757
+ if (data->key) FREE(data->key);
758
+ if (data->iv) FREE(data->iv);
759
+ if (data->ek) FREE(data->ek);
760
+ if (data->dk) FREE(data->dk);
761
+ FREE(data);
762
+ }
763
+ }
764
+
765
+ static VALUE
766
+ rb_aes_alloc(VALUE klass)
767
+ {
768
+ VALUE obj;
769
+ AES *data;
770
+
771
+ data = ALLOC(AES);
772
+ MEMZERO(data, AES, 1);
773
+
774
+ data->state = ALLOC_N(uchar, BLOCK_SIZE);
775
+ MEMZERO(data->state, uchar, BLOCK_SIZE);
776
+
777
+ data->state2 = ALLOC_N(uchar, BLOCK_SIZE);
778
+ MEMZERO(data->state2, uchar, BLOCK_SIZE);
779
+
780
+ data->key = ALLOC_N(uchar, 32);
781
+ MEMZERO(data->key, uchar, 32);
782
+
783
+ data->iv = ALLOC_N(uchar, BLOCK_SIZE);
784
+ MEMZERO(data->iv, uchar, BLOCK_SIZE);
785
+
786
+ obj = Data_Wrap_Struct(klass, rb_aes_mark, rb_aes_free, data);
787
+
788
+ return obj;
789
+ }
790
+
791
+ static VALUE
792
+ rb_aes_initialize(VALUE self, VALUE kl, VALUE mode, VALUE key, VALUE iv)
793
+ {
794
+ rb_aes_init(self, kl, mode, key, iv);
795
+
796
+ return Qnil;
797
+ }
798
+
799
+ void Init_aes_alg()
800
+ {
801
+ rb_cAes = rb_define_class("AesAlg", rb_cObject);
802
+ rb_define_alloc_func(rb_cAes, rb_aes_alloc);
803
+ rb_define_method(rb_cAes, "initialize", rb_aes_initialize, 4);
804
+ rb_define_method(rb_cAes, "init", rb_aes_init, 4);
805
+ rb_define_method(rb_cAes, "encrypt_block", rb_aes_encrypt_block, 1);
806
+ rb_define_method(rb_cAes, "decrypt_block", rb_aes_decrypt_block, 1);
807
+ rb_define_method(rb_cAes, "encrypt_blocks", rb_aes_encrypt_blocks, 1);
808
+ rb_define_method(rb_cAes, "decrypt_blocks", rb_aes_decrypt_blocks, 1);
809
+ rb_define_method(rb_cAes, "encrypt_buffer", rb_aes_encrypt_buffer, 1);
810
+ rb_define_method(rb_cAes, "decrypt_buffer", rb_aes_decrypt_buffer, 1);
811
+ rb_define_method(rb_cAes, "c_extension", rb_aes_c_extension, 0);
812
+ }