sayaes 1.1.1
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.
- checksums.yaml +7 -0
- data/CHANGELOG +2 -0
- data/README.rdoc +2 -0
- data/Rakefile +11 -0
- data/ext/sayaes/extconf.rb +13 -0
- data/ext/sayaes/sayaes.c +1234 -0
- data/ext/sayaes/sayaes.h +72 -0
- data/lib/sayaes.rb +6 -0
- data/lib/sayaes/badwords.rb +21 -0
- data/lib/sayaes/big.rb +81 -0
- data/lib/sayaes/core.rb +122 -0
- data/spec/lib/testutils.rb +5 -0
- data/spec/sayaes_benchmark.rb +144 -0
- data/spec/sayaes_spec.rb +235 -0
- data/spec/sayaes_spec_big.rb +88 -0
- metadata +62 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 6518dc99b77bc8afb254ef1c0b102c01f3c78527b3d6f8960876d64f1607cefe
|
|
4
|
+
data.tar.gz: 1c0ba2bf212cc9f142731fed8d4352e341aac669f5fd2c61b25660957e578db9
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: f2481b76fb068800bfa5ce88f13741ec116e1e26be8791164299992ec565f52c078b90846ee0c09e703ddde779f23375abcc754685ef1311b9f61703eacab3cd
|
|
7
|
+
data.tar.gz: 39106b94bf35dee63cb12e8c0a92a58d9079cd044e07eaefc563316f70d5cc4e35d8f0573dddba4076fec79dc2b3cbc02d898199cea2beb83cc376d7a8c6ffc3
|
data/CHANGELOG
ADDED
data/README.rdoc
ADDED
data/Rakefile
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Loads mkmf which is used to make makefiles for Ruby extensions
|
|
4
|
+
require 'mkmf'
|
|
5
|
+
|
|
6
|
+
# Give it a name
|
|
7
|
+
extension_name = 'sayaes'
|
|
8
|
+
|
|
9
|
+
# The destination
|
|
10
|
+
dir_config(extension_name)
|
|
11
|
+
|
|
12
|
+
# Do the work
|
|
13
|
+
create_makefile(extension_name)
|
data/ext/sayaes/sayaes.c
ADDED
|
@@ -0,0 +1,1234 @@
|
|
|
1
|
+
/*//////////////////////////////////////////////////////////////////////////////
|
|
2
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
3
|
+
//
|
|
4
|
+
// Sayaes Ruby/C library implementation.
|
|
5
|
+
// Implementation in C originally by Christophe Devine.
|
|
6
|
+
//
|
|
7
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
8
|
+
//////////////////////////////////////////////////////////////////////////////*/
|
|
9
|
+
|
|
10
|
+
#include <string.h>
|
|
11
|
+
#include <stdio.h>
|
|
12
|
+
#include <stdint.h>
|
|
13
|
+
|
|
14
|
+
#include "ruby.h"
|
|
15
|
+
#define INTEGER_PACK_MSWORD_FIRST 0x01
|
|
16
|
+
#define INTEGER_PACK_LSWORD_FIRST 0x02
|
|
17
|
+
#define INTEGER_PACK_MSBYTE_FIRST 0x10
|
|
18
|
+
#define INTEGER_PACK_LSBYTE_FIRST 0x20
|
|
19
|
+
#define INTEGER_PACK_NATIVE_BYTE_ORDER 0x40
|
|
20
|
+
#define INTEGER_PACK_2COMP 0x80
|
|
21
|
+
#define INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION 0x400
|
|
22
|
+
/* For rb_integer_unpack: */
|
|
23
|
+
#define INTEGER_PACK_FORCE_BIGNUM 0x100
|
|
24
|
+
#define INTEGER_PACK_NEGATIVE 0x200
|
|
25
|
+
/* Combinations: */
|
|
26
|
+
#define INTEGER_PACK_LITTLE_ENDIAN \
|
|
27
|
+
(INTEGER_PACK_LSWORD_FIRST | \
|
|
28
|
+
INTEGER_PACK_LSBYTE_FIRST)
|
|
29
|
+
#define INTEGER_PACK_BIG_ENDIAN \
|
|
30
|
+
(INTEGER_PACK_MSWORD_FIRST | \
|
|
31
|
+
INTEGER_PACK_MSBYTE_FIRST)
|
|
32
|
+
|
|
33
|
+
#include "sayaes.h"
|
|
34
|
+
|
|
35
|
+
/* Global boolean */
|
|
36
|
+
int sayaes_do_gen_tables = 1;
|
|
37
|
+
|
|
38
|
+
/* Old school. Oh yeah */
|
|
39
|
+
#ifndef RSTRING_PTR
|
|
40
|
+
#define RSTRING_PTR(s) (RSTRING(s)->ptr)
|
|
41
|
+
#define RSTRING_LEN(s) (RSTRING(s)->len)
|
|
42
|
+
#endif
|
|
43
|
+
|
|
44
|
+
/* Ruby buckets */
|
|
45
|
+
VALUE rb_cSayaes;
|
|
46
|
+
|
|
47
|
+
void Init_sayaes()
|
|
48
|
+
{
|
|
49
|
+
rb_cSayaes = rb_define_class("Sayaes", rb_cObject);
|
|
50
|
+
|
|
51
|
+
rb_define_alloc_func(rb_cSayaes, sayaes_alloc);
|
|
52
|
+
rb_define_method(rb_cSayaes, "initialize", sayaes_initialize, 1);
|
|
53
|
+
rb_define_method(rb_cSayaes, "encrypt", sayaes_encrypt, 1);
|
|
54
|
+
rb_define_method(rb_cSayaes, "decrypt", sayaes_decrypt, 1);
|
|
55
|
+
rb_define_method(rb_cSayaes, "encipher", sayaes_encipher, 1);
|
|
56
|
+
rb_define_method(rb_cSayaes, "decipher", sayaes_decipher, 1);
|
|
57
|
+
rb_define_method(rb_cSayaes, "init_feistel_ext", sayaes_init_feistel_ext, 2);
|
|
58
|
+
rb_define_method(rb_cSayaes, "key", sayaes_key, 0);
|
|
59
|
+
rb_define_method(rb_cSayaes, "r", sayaes_r, 0);
|
|
60
|
+
rb_define_method(rb_cSayaes, "l", sayaes_l, 0);
|
|
61
|
+
rb_define_method(rb_cSayaes, "w", sayaes_w, 0);
|
|
62
|
+
rb_define_method(rb_cSayaes, "prf_big", sayaes_prf_big, 1);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
VALUE sayaes_key(VALUE self)
|
|
66
|
+
{
|
|
67
|
+
/* get our "self" data structure (eg, member vars) */
|
|
68
|
+
sayaes_t* sayaes;
|
|
69
|
+
VALUE new_str;
|
|
70
|
+
|
|
71
|
+
Data_Get_Struct(self, sayaes_t, sayaes);
|
|
72
|
+
new_str = rb_str_new(sayaes->key, sayaes->key_bits/8);
|
|
73
|
+
return new_str;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
VALUE sayaes_alloc(VALUE klass)
|
|
78
|
+
{
|
|
79
|
+
/* Initialize our structs */
|
|
80
|
+
sayaes_t *sayaes = malloc(sizeof(sayaes_t));
|
|
81
|
+
|
|
82
|
+
/* Clear out memory */
|
|
83
|
+
memset(sayaes->key, 0, sizeof(sayaes->key));
|
|
84
|
+
memset(sayaes->erk, 0, sizeof(sayaes->erk));
|
|
85
|
+
memset(sayaes->drk, 0, sizeof(sayaes->drk));
|
|
86
|
+
memset(sayaes->initial_erk, 0, sizeof(sayaes->initial_erk));
|
|
87
|
+
memset(sayaes->initial_drk, 0, sizeof(sayaes->initial_drk));
|
|
88
|
+
|
|
89
|
+
return Data_Wrap_Struct(klass, sayaes_mark, sayaes_free, sayaes);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
VALUE sayaes_initialize(VALUE self, VALUE key)
|
|
93
|
+
{
|
|
94
|
+
/* get our "self" data structure (eg, member vars) */
|
|
95
|
+
sayaes_t* sayaes;
|
|
96
|
+
/* char error_mesg[350]; */
|
|
97
|
+
int key_bits;
|
|
98
|
+
char* key_data;
|
|
99
|
+
|
|
100
|
+
Data_Get_Struct(self, sayaes_t, sayaes);
|
|
101
|
+
|
|
102
|
+
key_data = StringValuePtr(key);
|
|
103
|
+
|
|
104
|
+
/* since the tables are global there's no need to generate them more than once
|
|
105
|
+
* regardless of how many instances there are of this object
|
|
106
|
+
*/
|
|
107
|
+
if( sayaes_do_gen_tables == 1 )
|
|
108
|
+
{
|
|
109
|
+
sayaes_gen_tables();
|
|
110
|
+
sayaes_do_gen_tables = 0;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/* if they are trying to use a number of bits that is larger that the key
|
|
114
|
+
* has available, truncate the bits to the key bits.
|
|
115
|
+
* ie., they pass a 128 bit key but pass keytype N256 we will use N128
|
|
116
|
+
*/
|
|
117
|
+
//key_bits = strlen(key_data)*8;
|
|
118
|
+
key_bits = RSTRING_LEN(key)*8;
|
|
119
|
+
switch(key_bits)
|
|
120
|
+
{
|
|
121
|
+
case 128:
|
|
122
|
+
case 192:
|
|
123
|
+
case 256:
|
|
124
|
+
sayaes->key_bits = key_bits;
|
|
125
|
+
memcpy(sayaes->key, key_data, key_bits/8);
|
|
126
|
+
/*printf("AES key=%s, bits=%d\n", sayaes->key, sayaes->key_bits);*/
|
|
127
|
+
break;
|
|
128
|
+
default:
|
|
129
|
+
//sprintf(error_mesg, "AES key must be 128, 192, or 256 bits in length (got %d): %s", key_bits, key_data);
|
|
130
|
+
rb_raise(rb_eArgError, "AES key must be 128, 192, or 256 bits in length");
|
|
131
|
+
return Qnil;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (sayaes_initialize_state(sayaes)) {
|
|
135
|
+
rb_raise(rb_eRuntimeError, "Failed to initialize AES internal state");
|
|
136
|
+
return Qnil;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
sayaes->l = 999; // the length of the set-1
|
|
140
|
+
sayaes->r = 12; // rounds count
|
|
141
|
+
sayaes->w = 10;
|
|
142
|
+
sayaes->h = sayaes->w >> 1;
|
|
143
|
+
sayaes->mask = ~( (~((uint64_t)0) << (sayaes->w-1) ) << 1);
|
|
144
|
+
sayaes->hmask = ~(~((uint64_t)0) << sayaes->h);
|
|
145
|
+
|
|
146
|
+
return Qtrue;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
void sayaes_module_shutdown( sayaes_t* sayaes )
|
|
150
|
+
{
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/* This method **MUST** be present even if it does nothing */
|
|
154
|
+
void sayaes_mark( sayaes_t* sayaes )
|
|
155
|
+
{
|
|
156
|
+
/*rb_gc_mark(??);
|
|
157
|
+
//should we mark each member here? */
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
void sayaes_free( sayaes_t* sayaes )
|
|
161
|
+
{
|
|
162
|
+
sayaes_module_shutdown(sayaes);
|
|
163
|
+
free(sayaes);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
VALUE sayaes_init_feistel_ext(VALUE self, VALUE rb_l, VALUE rb_r)
|
|
168
|
+
{
|
|
169
|
+
/* get our "self" data structure (eg, member vars) */
|
|
170
|
+
sayaes_t* sayaes;
|
|
171
|
+
Data_Get_Struct(self, sayaes_t, sayaes);
|
|
172
|
+
|
|
173
|
+
sayaes->l = NUM2ULL(rb_l); // the length of the set-1
|
|
174
|
+
sayaes->r = NUM2ULL(rb_r); // rounds count
|
|
175
|
+
sayaes->w = (LOG2(sayaes->l)+1) & 0xfffffffffffffffe;
|
|
176
|
+
sayaes->h = sayaes->w >> 1;
|
|
177
|
+
sayaes->mask = ~( (~((uint64_t)0) << (sayaes->w-1) ) << 1); // w=64 requires << 1
|
|
178
|
+
sayaes->hmask = ~(~((uint64_t)0) << sayaes->h);
|
|
179
|
+
return Qtrue;
|
|
180
|
+
}
|
|
181
|
+
VALUE sayaes_r(VALUE self)
|
|
182
|
+
{
|
|
183
|
+
/* get our "self" data structure (eg, member vars) */
|
|
184
|
+
sayaes_t* sayaes;
|
|
185
|
+
Data_Get_Struct(self, sayaes_t, sayaes);
|
|
186
|
+
return ULL2NUM(sayaes->r);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
VALUE sayaes_l(VALUE self)
|
|
190
|
+
{
|
|
191
|
+
/* get our "self" data structure (eg, member vars) */
|
|
192
|
+
sayaes_t* sayaes;
|
|
193
|
+
Data_Get_Struct(self, sayaes_t, sayaes);
|
|
194
|
+
return ULL2NUM(sayaes->l);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
VALUE sayaes_w(VALUE self)
|
|
198
|
+
{
|
|
199
|
+
/* get our "self" data structure (eg, member vars) */
|
|
200
|
+
sayaes_t* sayaes;
|
|
201
|
+
Data_Get_Struct(self, sayaes_t, sayaes);
|
|
202
|
+
return ULL2NUM(sayaes->w);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
VALUE sayaes_encipher(VALUE self, VALUE rb_x)
|
|
207
|
+
{
|
|
208
|
+
/* get our "self" data structure (eg, member vars) */
|
|
209
|
+
sayaes_t* sayaes;
|
|
210
|
+
uint64_t l;
|
|
211
|
+
uint8_t r;
|
|
212
|
+
uint64_t y;
|
|
213
|
+
uint8_t j;
|
|
214
|
+
|
|
215
|
+
Data_Get_Struct(self, sayaes_t, sayaes);
|
|
216
|
+
|
|
217
|
+
l = sayaes->l;
|
|
218
|
+
r = sayaes->r; // rounds count
|
|
219
|
+
y = NUM2ULL(rb_x); // plain text
|
|
220
|
+
|
|
221
|
+
if (y > l) // x can't be larger than l
|
|
222
|
+
rb_raise(rb_eArgError, "number can't be larger than the set size");
|
|
223
|
+
|
|
224
|
+
do {
|
|
225
|
+
for(j=0; j<r; j++) // r feistel rounds repeated
|
|
226
|
+
y = sayaes_round_e(sayaes, y, j);
|
|
227
|
+
} while( y > l); /* repeat if we aren't inside the set size l */
|
|
228
|
+
|
|
229
|
+
return ULL2NUM(y);
|
|
230
|
+
}
|
|
231
|
+
VALUE sayaes_decipher(VALUE self, VALUE rb_x)
|
|
232
|
+
{
|
|
233
|
+
/* get our "self" data structure (eg, member vars) */
|
|
234
|
+
sayaes_t* sayaes;
|
|
235
|
+
uint64_t l;
|
|
236
|
+
uint8_t r; // rounds count
|
|
237
|
+
uint64_t y; // plain text
|
|
238
|
+
uint8_t j;
|
|
239
|
+
|
|
240
|
+
Data_Get_Struct(self, sayaes_t, sayaes);
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
l = sayaes->l;
|
|
244
|
+
r = sayaes->r; // rounds count
|
|
245
|
+
y = NUM2ULL(rb_x); // plain text
|
|
246
|
+
|
|
247
|
+
if (y > l) // x can't be larger than l
|
|
248
|
+
rb_raise(rb_eArgError, "number can't be larger than the set size");
|
|
249
|
+
|
|
250
|
+
do {
|
|
251
|
+
for(j=0; j<r; j++) // r feistel rounds repeated
|
|
252
|
+
y = sayaes_round_d(sayaes, y, r-1-j);
|
|
253
|
+
} while( y > l); /* repeat if we aren't inside the set size l */
|
|
254
|
+
|
|
255
|
+
return ULL2NUM(y);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/* function sayaes_round, one feistel round for w=2h
|
|
259
|
+
x: 32bit, w: 5bit=1 to 32, j=8bit=0..255
|
|
260
|
+
*/
|
|
261
|
+
uint64_t sayaes_round_e(sayaes_t* sayaes, uint64_t x, uint8_t j)
|
|
262
|
+
{
|
|
263
|
+
uint64_t left = x >> sayaes->h; // moved below
|
|
264
|
+
uint64_t right = x & sayaes->hmask;
|
|
265
|
+
uint64_t ret = ((right << sayaes->h) | ( left ^ sayaes_prf(sayaes, right, j)));
|
|
266
|
+
return ret & sayaes->mask;
|
|
267
|
+
}
|
|
268
|
+
uint64_t sayaes_round_d(sayaes_t* sayaes,uint64_t x, uint8_t j)
|
|
269
|
+
{
|
|
270
|
+
uint64_t left = x >> sayaes->h;
|
|
271
|
+
uint64_t right = x & sayaes->hmask;
|
|
272
|
+
uint64_t ret = ((right ^ sayaes_prf(sayaes, left, j)) << sayaes->h) | left;
|
|
273
|
+
return ret & sayaes->mask;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/* The prf gets an aes block encryption upto 120 bits + 8 bit counter */
|
|
277
|
+
uint64_t sayaes_prf(sayaes_t* sayaes, uint64_t x, uint8_t j)
|
|
278
|
+
{
|
|
279
|
+
uint64_t *prf;
|
|
280
|
+
// h=5bits, a mask of 0x000...11111
|
|
281
|
+
uint8_t ciphertext[16], plaintext[16];
|
|
282
|
+
/* set the state back to the start to allow for correct encryption
|
|
283
|
+
everytime we are passed data to encrypt*/
|
|
284
|
+
if (sayaes_reinitialize_state(sayaes)) {
|
|
285
|
+
rb_raise(rb_eRuntimeError, "Failed to reinitialize AES internal state");
|
|
286
|
+
return Qnil;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
memset(ciphertext, 0, sizeof(ciphertext)); /* pad with 0's */
|
|
290
|
+
memset(plaintext, 0, sizeof(plaintext)); /* pad with 0's */
|
|
291
|
+
memcpy(plaintext, &x, sizeof(x)); /*rightmost is the x, right half of plaintext*/
|
|
292
|
+
plaintext[15] = (uint8_t)j; /* tweak is the leftmost */
|
|
293
|
+
sayaes_encrypt_block(sayaes, plaintext, ciphertext);
|
|
294
|
+
prf = (uint64_t*)ciphertext;
|
|
295
|
+
|
|
296
|
+
// we return half bits of the result
|
|
297
|
+
return (*prf) & sayaes->hmask;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
VALUE sayaes_prf_big(VALUE self, VALUE hxj)
|
|
301
|
+
{
|
|
302
|
+
sayaes_t* sayaes;
|
|
303
|
+
uint8_t ciphertext[16], plaintext[16];
|
|
304
|
+
unsigned long* pDataIn;
|
|
305
|
+
unsigned long* pDataOut;
|
|
306
|
+
|
|
307
|
+
Data_Get_Struct(self, sayaes_t, sayaes);
|
|
308
|
+
|
|
309
|
+
/* set the state back to the start to allow for correct encryption
|
|
310
|
+
everytime we are passed data to encrypt*/
|
|
311
|
+
if (sayaes_reinitialize_state(sayaes)) {
|
|
312
|
+
rb_raise(rb_eRuntimeError, "Failed to reinitialize AES internal state");
|
|
313
|
+
return Qnil;
|
|
314
|
+
}
|
|
315
|
+
memset(ciphertext, 0, sizeof(ciphertext));
|
|
316
|
+
memset(plaintext, 0, sizeof(plaintext));
|
|
317
|
+
pDataIn = (unsigned long *)plaintext;
|
|
318
|
+
rb_integer_pack(hxj, pDataIn, 4, 1, 0, INTEGER_PACK_BIG_ENDIAN);
|
|
319
|
+
sayaes_encrypt_block(sayaes, plaintext, ciphertext);
|
|
320
|
+
pDataOut = (unsigned long *)ciphertext;
|
|
321
|
+
return rb_integer_unpack(pDataOut, 4, 1, 0, INTEGER_PACK_BIG_ENDIAN);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
VALUE sayaes_encrypt(
|
|
326
|
+
VALUE self,
|
|
327
|
+
VALUE buffer
|
|
328
|
+
)
|
|
329
|
+
{
|
|
330
|
+
/* get our "self" data structure (eg, member vars) */
|
|
331
|
+
sayaes_t* sayaes;
|
|
332
|
+
char* pDataIn;
|
|
333
|
+
char* pDataOut;
|
|
334
|
+
int uiNumBytesIn;
|
|
335
|
+
unsigned char *pRead, *pWrite;
|
|
336
|
+
int puiNumBytesOut;
|
|
337
|
+
VALUE new_str;
|
|
338
|
+
|
|
339
|
+
Data_Get_Struct(self, sayaes_t, sayaes);
|
|
340
|
+
|
|
341
|
+
pDataIn = StringValuePtr(buffer);
|
|
342
|
+
uiNumBytesIn = RSTRING_LEN(buffer);
|
|
343
|
+
pDataOut = malloc((uiNumBytesIn + 15) & -16); /* auto-malloc min size in 16-byte increments */
|
|
344
|
+
|
|
345
|
+
pRead = (unsigned char*)pDataIn;
|
|
346
|
+
pWrite = (unsigned char*)pDataOut;
|
|
347
|
+
|
|
348
|
+
/*//////////////////////////////////////////////////////////////////////////
|
|
349
|
+
////////////////////////////////////////////////////////////////////////////
|
|
350
|
+
// This routine will encode all input bytes in entirety (AES always "succeeds")
|
|
351
|
+
*/
|
|
352
|
+
puiNumBytesOut = 0;
|
|
353
|
+
|
|
354
|
+
/* set the state back to the start to allow for correct encryption
|
|
355
|
+
* everytime we are passed data to encrypt
|
|
356
|
+
*/
|
|
357
|
+
if (sayaes_reinitialize_state(sayaes)) {
|
|
358
|
+
rb_raise(rb_eRuntimeError, "Failed to reinitialize AES internal state");
|
|
359
|
+
return Qnil;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/*//////////////////////////////////////////////////////////////////////////
|
|
363
|
+
////////////////////////////////////////////////////////////////////////////
|
|
364
|
+
// Perform block encodes 16 bytes at a time while we still have at least
|
|
365
|
+
// 16 bytes of input remaining.
|
|
366
|
+
*/
|
|
367
|
+
while( uiNumBytesIn >= 16 )
|
|
368
|
+
{
|
|
369
|
+
sayaes_encrypt_block(sayaes, pRead, pWrite);
|
|
370
|
+
pRead += 16; pWrite += 16;
|
|
371
|
+
uiNumBytesIn -= 16;
|
|
372
|
+
puiNumBytesOut += 16;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/*//////////////////////////////////////////////////////////////////////////
|
|
376
|
+
////////////////////////////////////////////////////////////////////////////
|
|
377
|
+
// Have to catch any straggling bytes that are left after encoding the
|
|
378
|
+
// 16-byte blocks. The policy here will be to pad the input with zeros.
|
|
379
|
+
*/
|
|
380
|
+
if( uiNumBytesIn > 0 )
|
|
381
|
+
{
|
|
382
|
+
unsigned char temp[16];
|
|
383
|
+
memset(temp, 0, sizeof(temp)); /* pad with 0's */
|
|
384
|
+
memcpy(temp, pRead, uiNumBytesIn);
|
|
385
|
+
sayaes_encrypt_block(sayaes, temp, pWrite);
|
|
386
|
+
puiNumBytesOut += 16;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/* return the encrypted string */
|
|
390
|
+
new_str = rb_str_new(pDataOut, puiNumBytesOut);
|
|
391
|
+
free(pDataOut);
|
|
392
|
+
return new_str;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
VALUE sayaes_decrypt(
|
|
396
|
+
VALUE self,
|
|
397
|
+
VALUE buffer
|
|
398
|
+
)
|
|
399
|
+
{
|
|
400
|
+
/* get our "self" data structure (eg, member vars) */
|
|
401
|
+
sayaes_t* sayaes;
|
|
402
|
+
char* pDataIn;
|
|
403
|
+
int uiNumBytesIn;
|
|
404
|
+
char* pDataOut;
|
|
405
|
+
unsigned char *pRead, *pWrite;
|
|
406
|
+
int puiNumBytesOut;
|
|
407
|
+
VALUE new_str;
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
Data_Get_Struct(self, sayaes_t, sayaes);
|
|
411
|
+
|
|
412
|
+
pDataIn = StringValuePtr(buffer);
|
|
413
|
+
uiNumBytesIn = RSTRING_LEN(buffer);
|
|
414
|
+
pDataOut = malloc((uiNumBytesIn + 15) & -16); /* auto-malloc min size in 16-byte increments */
|
|
415
|
+
|
|
416
|
+
pRead = (unsigned char*)pDataIn;
|
|
417
|
+
pWrite = (unsigned char*)pDataOut;
|
|
418
|
+
|
|
419
|
+
/*//////////////////////////////////////////////////////////////////////////
|
|
420
|
+
////////////////////////////////////////////////////////////////////////////
|
|
421
|
+
// AES does not fail, and this routine will encode all input bytes
|
|
422
|
+
// entirely.
|
|
423
|
+
*/
|
|
424
|
+
puiNumBytesOut = 0;
|
|
425
|
+
|
|
426
|
+
/* set the state back to the start to allow for correct decryption
|
|
427
|
+
// everytime we are passed data to decrypt
|
|
428
|
+
*/
|
|
429
|
+
if (sayaes_reinitialize_state(sayaes)) {
|
|
430
|
+
rb_raise(rb_eRuntimeError, "Failed to reinitialize AES internal state");
|
|
431
|
+
return Qnil;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/*//////////////////////////////////////////////////////////////////////////
|
|
435
|
+
////////////////////////////////////////////////////////////////////////////
|
|
436
|
+
// Perform block decrypts 16 bytes at a time while we still have at least
|
|
437
|
+
// 16 bytes of input remaining.
|
|
438
|
+
*/
|
|
439
|
+
while( uiNumBytesIn >= 16 )
|
|
440
|
+
{
|
|
441
|
+
sayaes_decrypt_block(sayaes, pRead, pWrite);
|
|
442
|
+
pRead += 16; pWrite += 16;
|
|
443
|
+
uiNumBytesIn -= 16;
|
|
444
|
+
puiNumBytesOut += 16;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/*//////////////////////////////////////////////////////////////////////////
|
|
448
|
+
////////////////////////////////////////////////////////////////////////////
|
|
449
|
+
// Have to catch any straggling bytes that are left after decrypting the
|
|
450
|
+
// 16-byte blocks.
|
|
451
|
+
*/
|
|
452
|
+
if( uiNumBytesIn > 0 )
|
|
453
|
+
{
|
|
454
|
+
unsigned char temp[16];
|
|
455
|
+
memset(temp, 0, sizeof(temp)); /* pad with 0's */
|
|
456
|
+
memcpy(temp, pRead, uiNumBytesIn);
|
|
457
|
+
sayaes_decrypt_block(sayaes, temp, pWrite);
|
|
458
|
+
puiNumBytesOut += 16;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/*//////////////////////////////////////////////////////////////////////////
|
|
462
|
+
////////////////////////////////////////////////////////////////////////////
|
|
463
|
+
// Strip trailing zeros, simple but effective. This is something fucking
|
|
464
|
+
// loose-cannon rjc couldn't figure out despite being a "genius". He needs
|
|
465
|
+
// a punch in the junk, I swear to god.
|
|
466
|
+
*/
|
|
467
|
+
while (puiNumBytesOut > 0) {
|
|
468
|
+
if (pDataOut[puiNumBytesOut - 1] != 0) break;
|
|
469
|
+
puiNumBytesOut -= 1;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/* return the decrypted string */
|
|
473
|
+
new_str = rb_str_new(pDataOut, puiNumBytesOut);
|
|
474
|
+
free(pDataOut);
|
|
475
|
+
return new_str;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/*//////////////////////////////////////////////////////////////////////////////
|
|
479
|
+
//////////////////////////////////////////////////////////////////////////////*/
|
|
480
|
+
|
|
481
|
+
/* uncomment the following line to use pre-computed tables */
|
|
482
|
+
/* otherwise the tables will be generated at the first run */
|
|
483
|
+
//#define FIXED_TABLES
|
|
484
|
+
|
|
485
|
+
#ifndef FIXED_TABLES
|
|
486
|
+
|
|
487
|
+
/* forward S-box & tables */
|
|
488
|
+
|
|
489
|
+
uint32_t FSb[256];
|
|
490
|
+
uint32_t FT0[256];
|
|
491
|
+
uint32_t FT1[256];
|
|
492
|
+
uint32_t FT2[256];
|
|
493
|
+
uint32_t FT3[256];
|
|
494
|
+
|
|
495
|
+
/* reverse S-box & tables */
|
|
496
|
+
|
|
497
|
+
uint32_t RSb[256];
|
|
498
|
+
uint32_t RT0[256];
|
|
499
|
+
uint32_t RT1[256];
|
|
500
|
+
uint32_t RT2[256];
|
|
501
|
+
uint32_t RT3[256];
|
|
502
|
+
|
|
503
|
+
/* round constants */
|
|
504
|
+
|
|
505
|
+
uint32_t RCON[10];
|
|
506
|
+
|
|
507
|
+
/* tables generation flag */
|
|
508
|
+
|
|
509
|
+
/* tables generation routine */
|
|
510
|
+
|
|
511
|
+
#define ROTR8(x) ( ( ( x << 24 ) & 0xFFFFFFFF ) | \
|
|
512
|
+
( ( x & 0xFFFFFFFF ) >> 8 ) )
|
|
513
|
+
|
|
514
|
+
#define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) )
|
|
515
|
+
#define MUL(x,y) ( ( x && y ) ? pow[(log[x] + log[y]) % 255] : 0 )
|
|
516
|
+
|
|
517
|
+
void sayaes_gen_tables( void )
|
|
518
|
+
{
|
|
519
|
+
int i;
|
|
520
|
+
uint8_t x, y;
|
|
521
|
+
uint8_t pow[256];
|
|
522
|
+
uint8_t log[256];
|
|
523
|
+
|
|
524
|
+
/* compute pow and log tables over GF(2^8) */
|
|
525
|
+
|
|
526
|
+
for( i = 0, x = 1; i < 256; i++, x ^= XTIME( x ) )
|
|
527
|
+
{
|
|
528
|
+
pow[i] = x;
|
|
529
|
+
log[x] = i;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/* calculate the round constants */
|
|
533
|
+
|
|
534
|
+
for( i = 0, x = 1; i < 10; i++, x = XTIME( x ) )
|
|
535
|
+
{
|
|
536
|
+
RCON[i] = (uint32_t) x << 24;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
/* generate the forward and reverse S-boxes */
|
|
540
|
+
|
|
541
|
+
FSb[0x00] = 0x63;
|
|
542
|
+
RSb[0x63] = 0x00;
|
|
543
|
+
|
|
544
|
+
for( i = 1; i < 256; ++i )
|
|
545
|
+
{
|
|
546
|
+
x = pow[255 - log[i]];
|
|
547
|
+
|
|
548
|
+
y = x; y = ( y << 1 ) | ( y >> 7 );
|
|
549
|
+
x ^= y; y = ( y << 1 ) | ( y >> 7 );
|
|
550
|
+
x ^= y; y = ( y << 1 ) | ( y >> 7 );
|
|
551
|
+
x ^= y; y = ( y << 1 ) | ( y >> 7 );
|
|
552
|
+
x ^= y ^ 0x63;
|
|
553
|
+
|
|
554
|
+
FSb[i] = x;
|
|
555
|
+
RSb[x] = i;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/* generate the forward and reverse tables */
|
|
559
|
+
|
|
560
|
+
for( i = 0; i < 256; ++i )
|
|
561
|
+
{
|
|
562
|
+
x = (unsigned char) FSb[i]; y = XTIME( x );
|
|
563
|
+
|
|
564
|
+
FT0[i] = (uint32_t) ( x ^ y ) ^
|
|
565
|
+
( (uint32_t) x << 8 ) ^
|
|
566
|
+
( (uint32_t) x << 16 ) ^
|
|
567
|
+
( (uint32_t) y << 24 );
|
|
568
|
+
|
|
569
|
+
FT0[i] &= 0xFFFFFFFF;
|
|
570
|
+
|
|
571
|
+
FT1[i] = ROTR8( FT0[i] );
|
|
572
|
+
FT2[i] = ROTR8( FT1[i] );
|
|
573
|
+
FT3[i] = ROTR8( FT2[i] );
|
|
574
|
+
|
|
575
|
+
y = (unsigned char) RSb[i];
|
|
576
|
+
|
|
577
|
+
RT0[i] = ( (uint32_t) MUL( 0x0B, y ) ) ^
|
|
578
|
+
( (uint32_t) MUL( 0x0D, y ) << 8 ) ^
|
|
579
|
+
( (uint32_t) MUL( 0x09, y ) << 16 ) ^
|
|
580
|
+
( (uint32_t) MUL( 0x0E, y ) << 24 );
|
|
581
|
+
|
|
582
|
+
RT0[i] &= 0xFFFFFFFF;
|
|
583
|
+
|
|
584
|
+
RT1[i] = ROTR8( RT0[i] );
|
|
585
|
+
RT2[i] = ROTR8( RT1[i] );
|
|
586
|
+
RT3[i] = ROTR8( RT2[i] );
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
#else
|
|
591
|
+
|
|
592
|
+
/* forward S-box */
|
|
593
|
+
|
|
594
|
+
static const uint32_t FSb[256] =
|
|
595
|
+
{
|
|
596
|
+
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
|
|
597
|
+
0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
|
|
598
|
+
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
|
|
599
|
+
0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
|
|
600
|
+
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
|
|
601
|
+
0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
|
|
602
|
+
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
|
|
603
|
+
0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
|
|
604
|
+
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
|
|
605
|
+
0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
|
|
606
|
+
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
|
|
607
|
+
0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
|
|
608
|
+
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
|
|
609
|
+
0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
|
|
610
|
+
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
|
|
611
|
+
0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
|
|
612
|
+
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
|
|
613
|
+
0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
|
|
614
|
+
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
|
|
615
|
+
0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
|
|
616
|
+
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
|
|
617
|
+
0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
|
|
618
|
+
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
|
|
619
|
+
0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
|
|
620
|
+
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
|
|
621
|
+
0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
|
|
622
|
+
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
|
|
623
|
+
0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
|
|
624
|
+
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
|
|
625
|
+
0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
|
|
626
|
+
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
|
|
627
|
+
0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
|
|
628
|
+
};
|
|
629
|
+
|
|
630
|
+
/* forward tables */
|
|
631
|
+
|
|
632
|
+
#define FT \
|
|
633
|
+
\
|
|
634
|
+
V(C6,63,63,A5), V(F8,7C,7C,84), V(EE,77,77,99), V(F6,7B,7B,8D), \
|
|
635
|
+
V(FF,F2,F2,0D), V(D6,6B,6B,BD), V(DE,6F,6F,B1), V(91,C5,C5,54), \
|
|
636
|
+
V(60,30,30,50), V(02,01,01,03), V(CE,67,67,A9), V(56,2B,2B,7D), \
|
|
637
|
+
V(E7,FE,FE,19), V(B5,D7,D7,62), V(4D,AB,AB,E6), V(EC,76,76,9A), \
|
|
638
|
+
V(8F,CA,CA,45), V(1F,82,82,9D), V(89,C9,C9,40), V(FA,7D,7D,87), \
|
|
639
|
+
V(EF,FA,FA,15), V(B2,59,59,EB), V(8E,47,47,C9), V(FB,F0,F0,0B), \
|
|
640
|
+
V(41,AD,AD,EC), V(B3,D4,D4,67), V(5F,A2,A2,FD), V(45,AF,AF,EA), \
|
|
641
|
+
V(23,9C,9C,BF), V(53,A4,A4,F7), V(E4,72,72,96), V(9B,C0,C0,5B), \
|
|
642
|
+
V(75,B7,B7,C2), V(E1,FD,FD,1C), V(3D,93,93,AE), V(4C,26,26,6A), \
|
|
643
|
+
V(6C,36,36,5A), V(7E,3F,3F,41), V(F5,F7,F7,02), V(83,CC,CC,4F), \
|
|
644
|
+
V(68,34,34,5C), V(51,A5,A5,F4), V(D1,E5,E5,34), V(F9,F1,F1,08), \
|
|
645
|
+
V(E2,71,71,93), V(AB,D8,D8,73), V(62,31,31,53), V(2A,15,15,3F), \
|
|
646
|
+
V(08,04,04,0C), V(95,C7,C7,52), V(46,23,23,65), V(9D,C3,C3,5E), \
|
|
647
|
+
V(30,18,18,28), V(37,96,96,A1), V(0A,05,05,0F), V(2F,9A,9A,B5), \
|
|
648
|
+
V(0E,07,07,09), V(24,12,12,36), V(1B,80,80,9B), V(DF,E2,E2,3D), \
|
|
649
|
+
V(CD,EB,EB,26), V(4E,27,27,69), V(7F,B2,B2,CD), V(EA,75,75,9F), \
|
|
650
|
+
V(12,09,09,1B), V(1D,83,83,9E), V(58,2C,2C,74), V(34,1A,1A,2E), \
|
|
651
|
+
V(36,1B,1B,2D), V(DC,6E,6E,B2), V(B4,5A,5A,EE), V(5B,A0,A0,FB), \
|
|
652
|
+
V(A4,52,52,F6), V(76,3B,3B,4D), V(B7,D6,D6,61), V(7D,B3,B3,CE), \
|
|
653
|
+
V(52,29,29,7B), V(DD,E3,E3,3E), V(5E,2F,2F,71), V(13,84,84,97), \
|
|
654
|
+
V(A6,53,53,F5), V(B9,D1,D1,68), V(00,00,00,00), V(C1,ED,ED,2C), \
|
|
655
|
+
V(40,20,20,60), V(E3,FC,FC,1F), V(79,B1,B1,C8), V(B6,5B,5B,ED), \
|
|
656
|
+
V(D4,6A,6A,BE), V(8D,CB,CB,46), V(67,BE,BE,D9), V(72,39,39,4B), \
|
|
657
|
+
V(94,4A,4A,DE), V(98,4C,4C,D4), V(B0,58,58,E8), V(85,CF,CF,4A), \
|
|
658
|
+
V(BB,D0,D0,6B), V(C5,EF,EF,2A), V(4F,AA,AA,E5), V(ED,FB,FB,16), \
|
|
659
|
+
V(86,43,43,C5), V(9A,4D,4D,D7), V(66,33,33,55), V(11,85,85,94), \
|
|
660
|
+
V(8A,45,45,CF), V(E9,F9,F9,10), V(04,02,02,06), V(FE,7F,7F,81), \
|
|
661
|
+
V(A0,50,50,F0), V(78,3C,3C,44), V(25,9F,9F,BA), V(4B,A8,A8,E3), \
|
|
662
|
+
V(A2,51,51,F3), V(5D,A3,A3,FE), V(80,40,40,C0), V(05,8F,8F,8A), \
|
|
663
|
+
V(3F,92,92,AD), V(21,9D,9D,BC), V(70,38,38,48), V(F1,F5,F5,04), \
|
|
664
|
+
V(63,BC,BC,DF), V(77,B6,B6,C1), V(AF,DA,DA,75), V(42,21,21,63), \
|
|
665
|
+
V(20,10,10,30), V(E5,FF,FF,1A), V(FD,F3,F3,0E), V(BF,D2,D2,6D), \
|
|
666
|
+
V(81,CD,CD,4C), V(18,0C,0C,14), V(26,13,13,35), V(C3,EC,EC,2F), \
|
|
667
|
+
V(BE,5F,5F,E1), V(35,97,97,A2), V(88,44,44,CC), V(2E,17,17,39), \
|
|
668
|
+
V(93,C4,C4,57), V(55,A7,A7,F2), V(FC,7E,7E,82), V(7A,3D,3D,47), \
|
|
669
|
+
V(C8,64,64,AC), V(BA,5D,5D,E7), V(32,19,19,2B), V(E6,73,73,95), \
|
|
670
|
+
V(C0,60,60,A0), V(19,81,81,98), V(9E,4F,4F,D1), V(A3,DC,DC,7F), \
|
|
671
|
+
V(44,22,22,66), V(54,2A,2A,7E), V(3B,90,90,AB), V(0B,88,88,83), \
|
|
672
|
+
V(8C,46,46,CA), V(C7,EE,EE,29), V(6B,B8,B8,D3), V(28,14,14,3C), \
|
|
673
|
+
V(A7,DE,DE,79), V(BC,5E,5E,E2), V(16,0B,0B,1D), V(AD,DB,DB,76), \
|
|
674
|
+
V(DB,E0,E0,3B), V(64,32,32,56), V(74,3A,3A,4E), V(14,0A,0A,1E), \
|
|
675
|
+
V(92,49,49,DB), V(0C,06,06,0A), V(48,24,24,6C), V(B8,5C,5C,E4), \
|
|
676
|
+
V(9F,C2,C2,5D), V(BD,D3,D3,6E), V(43,AC,AC,EF), V(C4,62,62,A6), \
|
|
677
|
+
V(39,91,91,A8), V(31,95,95,A4), V(D3,E4,E4,37), V(F2,79,79,8B), \
|
|
678
|
+
V(D5,E7,E7,32), V(8B,C8,C8,43), V(6E,37,37,59), V(DA,6D,6D,B7), \
|
|
679
|
+
V(01,8D,8D,8C), V(B1,D5,D5,64), V(9C,4E,4E,D2), V(49,A9,A9,E0), \
|
|
680
|
+
V(D8,6C,6C,B4), V(AC,56,56,FA), V(F3,F4,F4,07), V(CF,EA,EA,25), \
|
|
681
|
+
V(CA,65,65,AF), V(F4,7A,7A,8E), V(47,AE,AE,E9), V(10,08,08,18), \
|
|
682
|
+
V(6F,BA,BA,D5), V(F0,78,78,88), V(4A,25,25,6F), V(5C,2E,2E,72), \
|
|
683
|
+
V(38,1C,1C,24), V(57,A6,A6,F1), V(73,B4,B4,C7), V(97,C6,C6,51), \
|
|
684
|
+
V(CB,E8,E8,23), V(A1,DD,DD,7C), V(E8,74,74,9C), V(3E,1F,1F,21), \
|
|
685
|
+
V(96,4B,4B,DD), V(61,BD,BD,DC), V(0D,8B,8B,86), V(0F,8A,8A,85), \
|
|
686
|
+
V(E0,70,70,90), V(7C,3E,3E,42), V(71,B5,B5,C4), V(CC,66,66,AA), \
|
|
687
|
+
V(90,48,48,D8), V(06,03,03,05), V(F7,F6,F6,01), V(1C,0E,0E,12), \
|
|
688
|
+
V(C2,61,61,A3), V(6A,35,35,5F), V(AE,57,57,F9), V(69,B9,B9,D0), \
|
|
689
|
+
V(17,86,86,91), V(99,C1,C1,58), V(3A,1D,1D,27), V(27,9E,9E,B9), \
|
|
690
|
+
V(D9,E1,E1,38), V(EB,F8,F8,13), V(2B,98,98,B3), V(22,11,11,33), \
|
|
691
|
+
V(D2,69,69,BB), V(A9,D9,D9,70), V(07,8E,8E,89), V(33,94,94,A7), \
|
|
692
|
+
V(2D,9B,9B,B6), V(3C,1E,1E,22), V(15,87,87,92), V(C9,E9,E9,20), \
|
|
693
|
+
V(87,CE,CE,49), V(AA,55,55,FF), V(50,28,28,78), V(A5,DF,DF,7A), \
|
|
694
|
+
V(03,8C,8C,8F), V(59,A1,A1,F8), V(09,89,89,80), V(1A,0D,0D,17), \
|
|
695
|
+
V(65,BF,BF,DA), V(D7,E6,E6,31), V(84,42,42,C6), V(D0,68,68,B8), \
|
|
696
|
+
V(82,41,41,C3), V(29,99,99,B0), V(5A,2D,2D,77), V(1E,0F,0F,11), \
|
|
697
|
+
V(7B,B0,B0,CB), V(A8,54,54,FC), V(6D,BB,BB,D6), V(2C,16,16,3A)
|
|
698
|
+
|
|
699
|
+
#define V(a,b,c,d) 0x##a##b##c##d
|
|
700
|
+
static const uint32_t FT0[256] = { FT };
|
|
701
|
+
#undef V
|
|
702
|
+
|
|
703
|
+
#define V(a,b,c,d) 0x##d##a##b##c
|
|
704
|
+
static const uint32_t FT1[256] = { FT };
|
|
705
|
+
#undef V
|
|
706
|
+
|
|
707
|
+
#define V(a,b,c,d) 0x##c##d##a##b
|
|
708
|
+
static const uint32_t FT2[256] = { FT };
|
|
709
|
+
#undef V
|
|
710
|
+
|
|
711
|
+
#define V(a,b,c,d) 0x##b##c##d##a
|
|
712
|
+
static const uint32_t FT3[256] = { FT };
|
|
713
|
+
#undef V
|
|
714
|
+
|
|
715
|
+
#undef FT
|
|
716
|
+
|
|
717
|
+
/* reverse S-box */
|
|
718
|
+
|
|
719
|
+
static const uint32_t RSb[256] =
|
|
720
|
+
{
|
|
721
|
+
0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
|
|
722
|
+
0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
|
|
723
|
+
0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
|
|
724
|
+
0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
|
|
725
|
+
0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
|
|
726
|
+
0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
|
|
727
|
+
0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
|
|
728
|
+
0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
|
|
729
|
+
0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
|
|
730
|
+
0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
|
|
731
|
+
0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
|
|
732
|
+
0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
|
|
733
|
+
0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
|
|
734
|
+
0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
|
|
735
|
+
0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
|
|
736
|
+
0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
|
|
737
|
+
0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
|
|
738
|
+
0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
|
|
739
|
+
0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
|
|
740
|
+
0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
|
|
741
|
+
0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
|
|
742
|
+
0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
|
|
743
|
+
0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
|
|
744
|
+
0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
|
|
745
|
+
0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
|
|
746
|
+
0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
|
|
747
|
+
0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
|
|
748
|
+
0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
|
|
749
|
+
0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
|
|
750
|
+
0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
|
|
751
|
+
0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
|
|
752
|
+
0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
|
|
753
|
+
};
|
|
754
|
+
|
|
755
|
+
/* reverse tables */
|
|
756
|
+
|
|
757
|
+
#define RT \
|
|
758
|
+
\
|
|
759
|
+
V(51,F4,A7,50), V(7E,41,65,53), V(1A,17,A4,C3), V(3A,27,5E,96), \
|
|
760
|
+
V(3B,AB,6B,CB), V(1F,9D,45,F1), V(AC,FA,58,AB), V(4B,E3,03,93), \
|
|
761
|
+
V(20,30,FA,55), V(AD,76,6D,F6), V(88,CC,76,91), V(F5,02,4C,25), \
|
|
762
|
+
V(4F,E5,D7,FC), V(C5,2A,CB,D7), V(26,35,44,80), V(B5,62,A3,8F), \
|
|
763
|
+
V(DE,B1,5A,49), V(25,BA,1B,67), V(45,EA,0E,98), V(5D,FE,C0,E1), \
|
|
764
|
+
V(C3,2F,75,02), V(81,4C,F0,12), V(8D,46,97,A3), V(6B,D3,F9,C6), \
|
|
765
|
+
V(03,8F,5F,E7), V(15,92,9C,95), V(BF,6D,7A,EB), V(95,52,59,DA), \
|
|
766
|
+
V(D4,BE,83,2D), V(58,74,21,D3), V(49,E0,69,29), V(8E,C9,C8,44), \
|
|
767
|
+
V(75,C2,89,6A), V(F4,8E,79,78), V(99,58,3E,6B), V(27,B9,71,DD), \
|
|
768
|
+
V(BE,E1,4F,B6), V(F0,88,AD,17), V(C9,20,AC,66), V(7D,CE,3A,B4), \
|
|
769
|
+
V(63,DF,4A,18), V(E5,1A,31,82), V(97,51,33,60), V(62,53,7F,45), \
|
|
770
|
+
V(B1,64,77,E0), V(BB,6B,AE,84), V(FE,81,A0,1C), V(F9,08,2B,94), \
|
|
771
|
+
V(70,48,68,58), V(8F,45,FD,19), V(94,DE,6C,87), V(52,7B,F8,B7), \
|
|
772
|
+
V(AB,73,D3,23), V(72,4B,02,E2), V(E3,1F,8F,57), V(66,55,AB,2A), \
|
|
773
|
+
V(B2,EB,28,07), V(2F,B5,C2,03), V(86,C5,7B,9A), V(D3,37,08,A5), \
|
|
774
|
+
V(30,28,87,F2), V(23,BF,A5,B2), V(02,03,6A,BA), V(ED,16,82,5C), \
|
|
775
|
+
V(8A,CF,1C,2B), V(A7,79,B4,92), V(F3,07,F2,F0), V(4E,69,E2,A1), \
|
|
776
|
+
V(65,DA,F4,CD), V(06,05,BE,D5), V(D1,34,62,1F), V(C4,A6,FE,8A), \
|
|
777
|
+
V(34,2E,53,9D), V(A2,F3,55,A0), V(05,8A,E1,32), V(A4,F6,EB,75), \
|
|
778
|
+
V(0B,83,EC,39), V(40,60,EF,AA), V(5E,71,9F,06), V(BD,6E,10,51), \
|
|
779
|
+
V(3E,21,8A,F9), V(96,DD,06,3D), V(DD,3E,05,AE), V(4D,E6,BD,46), \
|
|
780
|
+
V(91,54,8D,B5), V(71,C4,5D,05), V(04,06,D4,6F), V(60,50,15,FF), \
|
|
781
|
+
V(19,98,FB,24), V(D6,BD,E9,97), V(89,40,43,CC), V(67,D9,9E,77), \
|
|
782
|
+
V(B0,E8,42,BD), V(07,89,8B,88), V(E7,19,5B,38), V(79,C8,EE,DB), \
|
|
783
|
+
V(A1,7C,0A,47), V(7C,42,0F,E9), V(F8,84,1E,C9), V(00,00,00,00), \
|
|
784
|
+
V(09,80,86,83), V(32,2B,ED,48), V(1E,11,70,AC), V(6C,5A,72,4E), \
|
|
785
|
+
V(FD,0E,FF,FB), V(0F,85,38,56), V(3D,AE,D5,1E), V(36,2D,39,27), \
|
|
786
|
+
V(0A,0F,D9,64), V(68,5C,A6,21), V(9B,5B,54,D1), V(24,36,2E,3A), \
|
|
787
|
+
V(0C,0A,67,B1), V(93,57,E7,0F), V(B4,EE,96,D2), V(1B,9B,91,9E), \
|
|
788
|
+
V(80,C0,C5,4F), V(61,DC,20,A2), V(5A,77,4B,69), V(1C,12,1A,16), \
|
|
789
|
+
V(E2,93,BA,0A), V(C0,A0,2A,E5), V(3C,22,E0,43), V(12,1B,17,1D), \
|
|
790
|
+
V(0E,09,0D,0B), V(F2,8B,C7,AD), V(2D,B6,A8,B9), V(14,1E,A9,C8), \
|
|
791
|
+
V(57,F1,19,85), V(AF,75,07,4C), V(EE,99,DD,BB), V(A3,7F,60,FD), \
|
|
792
|
+
V(F7,01,26,9F), V(5C,72,F5,BC), V(44,66,3B,C5), V(5B,FB,7E,34), \
|
|
793
|
+
V(8B,43,29,76), V(CB,23,C6,DC), V(B6,ED,FC,68), V(B8,E4,F1,63), \
|
|
794
|
+
V(D7,31,DC,CA), V(42,63,85,10), V(13,97,22,40), V(84,C6,11,20), \
|
|
795
|
+
V(85,4A,24,7D), V(D2,BB,3D,F8), V(AE,F9,32,11), V(C7,29,A1,6D), \
|
|
796
|
+
V(1D,9E,2F,4B), V(DC,B2,30,F3), V(0D,86,52,EC), V(77,C1,E3,D0), \
|
|
797
|
+
V(2B,B3,16,6C), V(A9,70,B9,99), V(11,94,48,FA), V(47,E9,64,22), \
|
|
798
|
+
V(A8,FC,8C,C4), V(A0,F0,3F,1A), V(56,7D,2C,D8), V(22,33,90,EF), \
|
|
799
|
+
V(87,49,4E,C7), V(D9,38,D1,C1), V(8C,CA,A2,FE), V(98,D4,0B,36), \
|
|
800
|
+
V(A6,F5,81,CF), V(A5,7A,DE,28), V(DA,B7,8E,26), V(3F,AD,BF,A4), \
|
|
801
|
+
V(2C,3A,9D,E4), V(50,78,92,0D), V(6A,5F,CC,9B), V(54,7E,46,62), \
|
|
802
|
+
V(F6,8D,13,C2), V(90,D8,B8,E8), V(2E,39,F7,5E), V(82,C3,AF,F5), \
|
|
803
|
+
V(9F,5D,80,BE), V(69,D0,93,7C), V(6F,D5,2D,A9), V(CF,25,12,B3), \
|
|
804
|
+
V(C8,AC,99,3B), V(10,18,7D,A7), V(E8,9C,63,6E), V(DB,3B,BB,7B), \
|
|
805
|
+
V(CD,26,78,09), V(6E,59,18,F4), V(EC,9A,B7,01), V(83,4F,9A,A8), \
|
|
806
|
+
V(E6,95,6E,65), V(AA,FF,E6,7E), V(21,BC,CF,08), V(EF,15,E8,E6), \
|
|
807
|
+
V(BA,E7,9B,D9), V(4A,6F,36,CE), V(EA,9F,09,D4), V(29,B0,7C,D6), \
|
|
808
|
+
V(31,A4,B2,AF), V(2A,3F,23,31), V(C6,A5,94,30), V(35,A2,66,C0), \
|
|
809
|
+
V(74,4E,BC,37), V(FC,82,CA,A6), V(E0,90,D0,B0), V(33,A7,D8,15), \
|
|
810
|
+
V(F1,04,98,4A), V(41,EC,DA,F7), V(7F,CD,50,0E), V(17,91,F6,2F), \
|
|
811
|
+
V(76,4D,D6,8D), V(43,EF,B0,4D), V(CC,AA,4D,54), V(E4,96,04,DF), \
|
|
812
|
+
V(9E,D1,B5,E3), V(4C,6A,88,1B), V(C1,2C,1F,B8), V(46,65,51,7F), \
|
|
813
|
+
V(9D,5E,EA,04), V(01,8C,35,5D), V(FA,87,74,73), V(FB,0B,41,2E), \
|
|
814
|
+
V(B3,67,1D,5A), V(92,DB,D2,52), V(E9,10,56,33), V(6D,D6,47,13), \
|
|
815
|
+
V(9A,D7,61,8C), V(37,A1,0C,7A), V(59,F8,14,8E), V(EB,13,3C,89), \
|
|
816
|
+
V(CE,A9,27,EE), V(B7,61,C9,35), V(E1,1C,E5,ED), V(7A,47,B1,3C), \
|
|
817
|
+
V(9C,D2,DF,59), V(55,F2,73,3F), V(18,14,CE,79), V(73,C7,37,BF), \
|
|
818
|
+
V(53,F7,CD,EA), V(5F,FD,AA,5B), V(DF,3D,6F,14), V(78,44,DB,86), \
|
|
819
|
+
V(CA,AF,F3,81), V(B9,68,C4,3E), V(38,24,34,2C), V(C2,A3,40,5F), \
|
|
820
|
+
V(16,1D,C3,72), V(BC,E2,25,0C), V(28,3C,49,8B), V(FF,0D,95,41), \
|
|
821
|
+
V(39,A8,01,71), V(08,0C,B3,DE), V(D8,B4,E4,9C), V(64,56,C1,90), \
|
|
822
|
+
V(7B,CB,84,61), V(D5,32,B6,70), V(48,6C,5C,74), V(D0,B8,57,42)
|
|
823
|
+
|
|
824
|
+
#define V(a,b,c,d) 0x##a##b##c##d
|
|
825
|
+
static const uint32_t RT0[256] = { RT };
|
|
826
|
+
#undef V
|
|
827
|
+
|
|
828
|
+
#define V(a,b,c,d) 0x##d##a##b##c
|
|
829
|
+
static const uint32_t RT1[256] = { RT };
|
|
830
|
+
#undef V
|
|
831
|
+
|
|
832
|
+
#define V(a,b,c,d) 0x##c##d##a##b
|
|
833
|
+
static const uint32_t RT2[256] = { RT };
|
|
834
|
+
#undef V
|
|
835
|
+
|
|
836
|
+
#define V(a,b,c,d) 0x##b##c##d##a
|
|
837
|
+
static const uint32_t RT3[256] = { RT };
|
|
838
|
+
#undef V
|
|
839
|
+
|
|
840
|
+
#undef RT
|
|
841
|
+
|
|
842
|
+
/* round constants */
|
|
843
|
+
|
|
844
|
+
static const uint32_t RCON[10] =
|
|
845
|
+
{
|
|
846
|
+
0x01000000, 0x02000000, 0x04000000, 0x08000000,
|
|
847
|
+
0x10000000, 0x20000000, 0x40000000, 0x80000000,
|
|
848
|
+
0x1B000000, 0x36000000
|
|
849
|
+
};
|
|
850
|
+
|
|
851
|
+
void aes_gen_tables( void )
|
|
852
|
+
{
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
#endif
|
|
856
|
+
|
|
857
|
+
/* platform-independant 32-bit integer manipulation macros */
|
|
858
|
+
|
|
859
|
+
#define GET_UINT32(n,b,i) \
|
|
860
|
+
{ \
|
|
861
|
+
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
|
|
862
|
+
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
|
|
863
|
+
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
|
|
864
|
+
| ( (uint32_t) (b)[(i) + 3] ); \
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
#define PUT_UINT32(n,b,i) \
|
|
868
|
+
{ \
|
|
869
|
+
(b)[(i) ] = (uint8_t) ( (n) >> 24 ); \
|
|
870
|
+
(b)[(i) + 1] = (uint8_t) ( (n) >> 16 ); \
|
|
871
|
+
(b)[(i) + 2] = (uint8_t) ( (n) >> 8 ); \
|
|
872
|
+
(b)[(i) + 3] = (uint8_t) ( (n) ); \
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
/* decryption key schedule tables */
|
|
876
|
+
|
|
877
|
+
int KT_init = 1;
|
|
878
|
+
|
|
879
|
+
uint32_t KT0[256];
|
|
880
|
+
uint32_t KT1[256];
|
|
881
|
+
uint32_t KT2[256];
|
|
882
|
+
uint32_t KT3[256];
|
|
883
|
+
|
|
884
|
+
uint32_t initial_KT0[256];
|
|
885
|
+
uint32_t initial_KT1[256];
|
|
886
|
+
uint32_t initial_KT2[256];
|
|
887
|
+
uint32_t initial_KT3[256];
|
|
888
|
+
|
|
889
|
+
/* AES key scheduling routine */
|
|
890
|
+
|
|
891
|
+
int
|
|
892
|
+
sayaes_initialize_state(sayaes_t* sayaes)
|
|
893
|
+
{
|
|
894
|
+
int i;
|
|
895
|
+
uint32_t *RK, *SK;
|
|
896
|
+
|
|
897
|
+
switch( sayaes->key_bits )
|
|
898
|
+
{
|
|
899
|
+
case 128: sayaes->nr = 10; break;
|
|
900
|
+
case 192: sayaes->nr = 12; break;
|
|
901
|
+
case 256: sayaes->nr = 14; break;
|
|
902
|
+
default : return( 1 );
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
RK = sayaes->erk;
|
|
906
|
+
|
|
907
|
+
for( i = 0; i < (sayaes->key_bits >> 5); ++i )
|
|
908
|
+
{
|
|
909
|
+
GET_UINT32(
|
|
910
|
+
sayaes->erk[i],
|
|
911
|
+
((unsigned char*)sayaes->key),
|
|
912
|
+
i * 4
|
|
913
|
+
);
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
/* setup encryption round keys */
|
|
917
|
+
|
|
918
|
+
switch( sayaes->key_bits )
|
|
919
|
+
{
|
|
920
|
+
case 128:
|
|
921
|
+
|
|
922
|
+
for( i = 0; i < 10; ++i, RK += 4 )
|
|
923
|
+
{
|
|
924
|
+
RK[4] = RK[0] ^ RCON[i] ^
|
|
925
|
+
( FSb[ (uint8_t) ( RK[3] >> 16 ) ] << 24 ) ^
|
|
926
|
+
( FSb[ (uint8_t) ( RK[3] >> 8 ) ] << 16 ) ^
|
|
927
|
+
( FSb[ (uint8_t) ( RK[3] ) ] << 8 ) ^
|
|
928
|
+
( FSb[ (uint8_t) ( RK[3] >> 24 ) ] );
|
|
929
|
+
|
|
930
|
+
RK[5] = RK[1] ^ RK[4];
|
|
931
|
+
RK[6] = RK[2] ^ RK[5];
|
|
932
|
+
RK[7] = RK[3] ^ RK[6];
|
|
933
|
+
}
|
|
934
|
+
break;
|
|
935
|
+
|
|
936
|
+
case 192:
|
|
937
|
+
|
|
938
|
+
for( i = 0; i < 8; ++i, RK += 6 )
|
|
939
|
+
{
|
|
940
|
+
RK[6] = RK[0] ^ RCON[i] ^
|
|
941
|
+
( FSb[ (uint8_t) ( RK[5] >> 16 ) ] << 24 ) ^
|
|
942
|
+
( FSb[ (uint8_t) ( RK[5] >> 8 ) ] << 16 ) ^
|
|
943
|
+
( FSb[ (uint8_t) ( RK[5] ) ] << 8 ) ^
|
|
944
|
+
( FSb[ (uint8_t) ( RK[5] >> 24 ) ] );
|
|
945
|
+
|
|
946
|
+
RK[7] = RK[1] ^ RK[6];
|
|
947
|
+
RK[8] = RK[2] ^ RK[7];
|
|
948
|
+
RK[9] = RK[3] ^ RK[8];
|
|
949
|
+
RK[10] = RK[4] ^ RK[9];
|
|
950
|
+
RK[11] = RK[5] ^ RK[10];
|
|
951
|
+
}
|
|
952
|
+
break;
|
|
953
|
+
|
|
954
|
+
case 256:
|
|
955
|
+
|
|
956
|
+
for( i = 0; i < 7; ++i, RK += 8 )
|
|
957
|
+
{
|
|
958
|
+
RK[8] = RK[0] ^ RCON[i] ^
|
|
959
|
+
( FSb[ (uint8_t) ( RK[7] >> 16 ) ] << 24 ) ^
|
|
960
|
+
( FSb[ (uint8_t) ( RK[7] >> 8 ) ] << 16 ) ^
|
|
961
|
+
( FSb[ (uint8_t) ( RK[7] ) ] << 8 ) ^
|
|
962
|
+
( FSb[ (uint8_t) ( RK[7] >> 24 ) ] );
|
|
963
|
+
|
|
964
|
+
RK[9] = RK[1] ^ RK[8];
|
|
965
|
+
RK[10] = RK[2] ^ RK[9];
|
|
966
|
+
RK[11] = RK[3] ^ RK[10];
|
|
967
|
+
|
|
968
|
+
RK[12] = RK[4] ^
|
|
969
|
+
( FSb[ (uint8_t) ( RK[11] >> 24 ) ] << 24 ) ^
|
|
970
|
+
( FSb[ (uint8_t) ( RK[11] >> 16 ) ] << 16 ) ^
|
|
971
|
+
( FSb[ (uint8_t) ( RK[11] >> 8 ) ] << 8 ) ^
|
|
972
|
+
( FSb[ (uint8_t) ( RK[11] ) ] );
|
|
973
|
+
|
|
974
|
+
RK[13] = RK[5] ^ RK[12];
|
|
975
|
+
RK[14] = RK[6] ^ RK[13];
|
|
976
|
+
RK[15] = RK[7] ^ RK[14];
|
|
977
|
+
}
|
|
978
|
+
break;
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
/* setup decryption round keys */
|
|
982
|
+
|
|
983
|
+
if( KT_init )
|
|
984
|
+
{
|
|
985
|
+
for( i = 0; i < 256; ++i )
|
|
986
|
+
{
|
|
987
|
+
KT0[i] = RT0[ FSb[i] ];
|
|
988
|
+
KT1[i] = RT1[ FSb[i] ];
|
|
989
|
+
KT2[i] = RT2[ FSb[i] ];
|
|
990
|
+
KT3[i] = RT3[ FSb[i] ];
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
KT_init = 0;
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
SK = sayaes->drk;
|
|
997
|
+
|
|
998
|
+
*SK++ = *RK++;
|
|
999
|
+
*SK++ = *RK++;
|
|
1000
|
+
*SK++ = *RK++;
|
|
1001
|
+
*SK++ = *RK++;
|
|
1002
|
+
|
|
1003
|
+
for( i = 1; i < sayaes->nr; ++i )
|
|
1004
|
+
{
|
|
1005
|
+
RK -= 8;
|
|
1006
|
+
|
|
1007
|
+
*SK++ = KT0[ (uint8_t) ( *RK >> 24 ) ] ^
|
|
1008
|
+
KT1[ (uint8_t) ( *RK >> 16 ) ] ^
|
|
1009
|
+
KT2[ (uint8_t) ( *RK >> 8 ) ] ^
|
|
1010
|
+
KT3[ (uint8_t) ( *RK ) ]; RK++;
|
|
1011
|
+
|
|
1012
|
+
*SK++ = KT0[ (uint8_t) ( *RK >> 24 ) ] ^
|
|
1013
|
+
KT1[ (uint8_t) ( *RK >> 16 ) ] ^
|
|
1014
|
+
KT2[ (uint8_t) ( *RK >> 8 ) ] ^
|
|
1015
|
+
KT3[ (uint8_t) ( *RK ) ]; RK++;
|
|
1016
|
+
|
|
1017
|
+
*SK++ = KT0[ (uint8_t) ( *RK >> 24 ) ] ^
|
|
1018
|
+
KT1[ (uint8_t) ( *RK >> 16 ) ] ^
|
|
1019
|
+
KT2[ (uint8_t) ( *RK >> 8 ) ] ^
|
|
1020
|
+
KT3[ (uint8_t) ( *RK ) ]; RK++;
|
|
1021
|
+
|
|
1022
|
+
*SK++ = KT0[ (uint8_t) ( *RK >> 24 ) ] ^
|
|
1023
|
+
KT1[ (uint8_t) ( *RK >> 16 ) ] ^
|
|
1024
|
+
KT2[ (uint8_t) ( *RK >> 8 ) ] ^
|
|
1025
|
+
KT3[ (uint8_t) ( *RK ) ]; RK++;
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
RK -= 8;
|
|
1029
|
+
|
|
1030
|
+
*SK++ = *RK++;
|
|
1031
|
+
*SK++ = *RK++;
|
|
1032
|
+
*SK++ = *RK++;
|
|
1033
|
+
*SK++ = *RK++;
|
|
1034
|
+
|
|
1035
|
+
/* setup values for quick re-initialization */
|
|
1036
|
+
memcpy(sayaes->initial_erk, sayaes->erk, sizeof(sayaes->initial_erk));
|
|
1037
|
+
memcpy(sayaes->initial_drk, sayaes->drk, sizeof(sayaes->initial_drk));
|
|
1038
|
+
return 0;
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
int
|
|
1042
|
+
sayaes_reinitialize_state(sayaes_t* sayaes)
|
|
1043
|
+
{
|
|
1044
|
+
/* put round keys for encryption and decryption back to their initial
|
|
1045
|
+
// states so we can encrypt and decrypt new items properly
|
|
1046
|
+
*/
|
|
1047
|
+
memcpy(sayaes->erk, sayaes->initial_erk, sizeof(sayaes->initial_erk));
|
|
1048
|
+
memcpy(sayaes->drk, sayaes->initial_drk, sizeof(sayaes->initial_drk));
|
|
1049
|
+
|
|
1050
|
+
return 0;
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
/* AES 128-bit block encryption routine */
|
|
1054
|
+
|
|
1055
|
+
void
|
|
1056
|
+
sayaes_encrypt_block(sayaes_t* sayaes, uint8_t input[16], uint8_t output[16])
|
|
1057
|
+
{
|
|
1058
|
+
uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
|
|
1059
|
+
|
|
1060
|
+
RK = sayaes->erk;
|
|
1061
|
+
|
|
1062
|
+
GET_UINT32( X0, input, 0 ); X0 ^= RK[0];
|
|
1063
|
+
GET_UINT32( X1, input, 4 ); X1 ^= RK[1];
|
|
1064
|
+
GET_UINT32( X2, input, 8 ); X2 ^= RK[2];
|
|
1065
|
+
GET_UINT32( X3, input, 12 ); X3 ^= RK[3];
|
|
1066
|
+
|
|
1067
|
+
#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
|
|
1068
|
+
{ \
|
|
1069
|
+
RK += 4; \
|
|
1070
|
+
\
|
|
1071
|
+
X0 = RK[0] ^ FT0[ (uint8_t) ( Y0 >> 24 ) ] ^ \
|
|
1072
|
+
FT1[ (uint8_t) ( Y1 >> 16 ) ] ^ \
|
|
1073
|
+
FT2[ (uint8_t) ( Y2 >> 8 ) ] ^ \
|
|
1074
|
+
FT3[ (uint8_t) ( Y3 ) ]; \
|
|
1075
|
+
\
|
|
1076
|
+
X1 = RK[1] ^ FT0[ (uint8_t) ( Y1 >> 24 ) ] ^ \
|
|
1077
|
+
FT1[ (uint8_t) ( Y2 >> 16 ) ] ^ \
|
|
1078
|
+
FT2[ (uint8_t) ( Y3 >> 8 ) ] ^ \
|
|
1079
|
+
FT3[ (uint8_t) ( Y0 ) ]; \
|
|
1080
|
+
\
|
|
1081
|
+
X2 = RK[2] ^ FT0[ (uint8_t) ( Y2 >> 24 ) ] ^ \
|
|
1082
|
+
FT1[ (uint8_t) ( Y3 >> 16 ) ] ^ \
|
|
1083
|
+
FT2[ (uint8_t) ( Y0 >> 8 ) ] ^ \
|
|
1084
|
+
FT3[ (uint8_t) ( Y1 ) ]; \
|
|
1085
|
+
\
|
|
1086
|
+
X3 = RK[3] ^ FT0[ (uint8_t) ( Y3 >> 24 ) ] ^ \
|
|
1087
|
+
FT1[ (uint8_t) ( Y0 >> 16 ) ] ^ \
|
|
1088
|
+
FT2[ (uint8_t) ( Y1 >> 8 ) ] ^ \
|
|
1089
|
+
FT3[ (uint8_t) ( Y2 ) ]; \
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 1 */
|
|
1093
|
+
AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 2 */
|
|
1094
|
+
AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 3 */
|
|
1095
|
+
AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 4 */
|
|
1096
|
+
AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 5 */
|
|
1097
|
+
AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 6 */
|
|
1098
|
+
AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 7 */
|
|
1099
|
+
AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 8 */
|
|
1100
|
+
AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 9 */
|
|
1101
|
+
|
|
1102
|
+
if( sayaes->nr > 10 )
|
|
1103
|
+
{
|
|
1104
|
+
AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 10 */
|
|
1105
|
+
AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 11 */
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1108
|
+
if( sayaes->nr > 12 )
|
|
1109
|
+
{
|
|
1110
|
+
AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 12 */
|
|
1111
|
+
AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 13 */
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
/* last round */
|
|
1115
|
+
|
|
1116
|
+
RK += 4;
|
|
1117
|
+
|
|
1118
|
+
X0 = RK[0] ^ ( FSb[ (uint8_t) ( Y0 >> 24 ) ] << 24 ) ^
|
|
1119
|
+
( FSb[ (uint8_t) ( Y1 >> 16 ) ] << 16 ) ^
|
|
1120
|
+
( FSb[ (uint8_t) ( Y2 >> 8 ) ] << 8 ) ^
|
|
1121
|
+
( FSb[ (uint8_t) ( Y3 ) ] );
|
|
1122
|
+
|
|
1123
|
+
X1 = RK[1] ^ ( FSb[ (uint8_t) ( Y1 >> 24 ) ] << 24 ) ^
|
|
1124
|
+
( FSb[ (uint8_t) ( Y2 >> 16 ) ] << 16 ) ^
|
|
1125
|
+
( FSb[ (uint8_t) ( Y3 >> 8 ) ] << 8 ) ^
|
|
1126
|
+
( FSb[ (uint8_t) ( Y0 ) ] );
|
|
1127
|
+
|
|
1128
|
+
X2 = RK[2] ^ ( FSb[ (uint8_t) ( Y2 >> 24 ) ] << 24 ) ^
|
|
1129
|
+
( FSb[ (uint8_t) ( Y3 >> 16 ) ] << 16 ) ^
|
|
1130
|
+
( FSb[ (uint8_t) ( Y0 >> 8 ) ] << 8 ) ^
|
|
1131
|
+
( FSb[ (uint8_t) ( Y1 ) ] );
|
|
1132
|
+
|
|
1133
|
+
X3 = RK[3] ^ ( FSb[ (uint8_t) ( Y3 >> 24 ) ] << 24 ) ^
|
|
1134
|
+
( FSb[ (uint8_t) ( Y0 >> 16 ) ] << 16 ) ^
|
|
1135
|
+
( FSb[ (uint8_t) ( Y1 >> 8 ) ] << 8 ) ^
|
|
1136
|
+
( FSb[ (uint8_t) ( Y2 ) ] );
|
|
1137
|
+
|
|
1138
|
+
PUT_UINT32( X0, output, 0 );
|
|
1139
|
+
PUT_UINT32( X1, output, 4 );
|
|
1140
|
+
PUT_UINT32( X2, output, 8 );
|
|
1141
|
+
PUT_UINT32( X3, output, 12 );
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
/* AES 128-bit block decryption routine */
|
|
1145
|
+
|
|
1146
|
+
void
|
|
1147
|
+
sayaes_decrypt_block(sayaes_t* sayaes, uint8_t input[16], uint8_t output[16])
|
|
1148
|
+
{
|
|
1149
|
+
uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
|
|
1150
|
+
|
|
1151
|
+
RK = sayaes->drk;
|
|
1152
|
+
|
|
1153
|
+
GET_UINT32( X0, input, 0 ); X0 ^= RK[0];
|
|
1154
|
+
GET_UINT32( X1, input, 4 ); X1 ^= RK[1];
|
|
1155
|
+
GET_UINT32( X2, input, 8 ); X2 ^= RK[2];
|
|
1156
|
+
GET_UINT32( X3, input, 12 ); X3 ^= RK[3];
|
|
1157
|
+
|
|
1158
|
+
#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
|
|
1159
|
+
{ \
|
|
1160
|
+
RK += 4; \
|
|
1161
|
+
\
|
|
1162
|
+
X0 = RK[0] ^ RT0[ (uint8_t) ( Y0 >> 24 ) ] ^ \
|
|
1163
|
+
RT1[ (uint8_t) ( Y3 >> 16 ) ] ^ \
|
|
1164
|
+
RT2[ (uint8_t) ( Y2 >> 8 ) ] ^ \
|
|
1165
|
+
RT3[ (uint8_t) ( Y1 ) ]; \
|
|
1166
|
+
\
|
|
1167
|
+
X1 = RK[1] ^ RT0[ (uint8_t) ( Y1 >> 24 ) ] ^ \
|
|
1168
|
+
RT1[ (uint8_t) ( Y0 >> 16 ) ] ^ \
|
|
1169
|
+
RT2[ (uint8_t) ( Y3 >> 8 ) ] ^ \
|
|
1170
|
+
RT3[ (uint8_t) ( Y2 ) ]; \
|
|
1171
|
+
\
|
|
1172
|
+
X2 = RK[2] ^ RT0[ (uint8_t) ( Y2 >> 24 ) ] ^ \
|
|
1173
|
+
RT1[ (uint8_t) ( Y1 >> 16 ) ] ^ \
|
|
1174
|
+
RT2[ (uint8_t) ( Y0 >> 8 ) ] ^ \
|
|
1175
|
+
RT3[ (uint8_t) ( Y3 ) ]; \
|
|
1176
|
+
\
|
|
1177
|
+
X3 = RK[3] ^ RT0[ (uint8_t) ( Y3 >> 24 ) ] ^ \
|
|
1178
|
+
RT1[ (uint8_t) ( Y2 >> 16 ) ] ^ \
|
|
1179
|
+
RT2[ (uint8_t) ( Y1 >> 8 ) ] ^ \
|
|
1180
|
+
RT3[ (uint8_t) ( Y0 ) ]; \
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 1 */
|
|
1184
|
+
AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 2 */
|
|
1185
|
+
AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 3 */
|
|
1186
|
+
AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 4 */
|
|
1187
|
+
AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 5 */
|
|
1188
|
+
AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 6 */
|
|
1189
|
+
AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 7 */
|
|
1190
|
+
AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 8 */
|
|
1191
|
+
AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 9 */
|
|
1192
|
+
|
|
1193
|
+
if( sayaes->nr > 10 )
|
|
1194
|
+
{
|
|
1195
|
+
AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 10 */
|
|
1196
|
+
AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 11 */
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
if( sayaes->nr > 12 )
|
|
1200
|
+
{
|
|
1201
|
+
AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 12 */
|
|
1202
|
+
AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 13 */
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
/* last round */
|
|
1206
|
+
|
|
1207
|
+
RK += 4;
|
|
1208
|
+
|
|
1209
|
+
X0 = RK[0] ^ ( RSb[ (uint8_t) ( Y0 >> 24 ) ] << 24 ) ^
|
|
1210
|
+
( RSb[ (uint8_t) ( Y3 >> 16 ) ] << 16 ) ^
|
|
1211
|
+
( RSb[ (uint8_t) ( Y2 >> 8 ) ] << 8 ) ^
|
|
1212
|
+
( RSb[ (uint8_t) ( Y1 ) ] );
|
|
1213
|
+
|
|
1214
|
+
X1 = RK[1] ^ ( RSb[ (uint8_t) ( Y1 >> 24 ) ] << 24 ) ^
|
|
1215
|
+
( RSb[ (uint8_t) ( Y0 >> 16 ) ] << 16 ) ^
|
|
1216
|
+
( RSb[ (uint8_t) ( Y3 >> 8 ) ] << 8 ) ^
|
|
1217
|
+
( RSb[ (uint8_t) ( Y2 ) ] );
|
|
1218
|
+
|
|
1219
|
+
X2 = RK[2] ^ ( RSb[ (uint8_t) ( Y2 >> 24 ) ] << 24 ) ^
|
|
1220
|
+
( RSb[ (uint8_t) ( Y1 >> 16 ) ] << 16 ) ^
|
|
1221
|
+
( RSb[ (uint8_t) ( Y0 >> 8 ) ] << 8 ) ^
|
|
1222
|
+
( RSb[ (uint8_t) ( Y3 ) ] );
|
|
1223
|
+
|
|
1224
|
+
X3 = RK[3] ^ ( RSb[ (uint8_t) ( Y3 >> 24 ) ] << 24 ) ^
|
|
1225
|
+
( RSb[ (uint8_t) ( Y2 >> 16 ) ] << 16 ) ^
|
|
1226
|
+
( RSb[ (uint8_t) ( Y1 >> 8 ) ] << 8 ) ^
|
|
1227
|
+
( RSb[ (uint8_t) ( Y0 ) ] );
|
|
1228
|
+
|
|
1229
|
+
PUT_UINT32( X0, output, 0 );
|
|
1230
|
+
PUT_UINT32( X1, output, 4 );
|
|
1231
|
+
PUT_UINT32( X2, output, 8 );
|
|
1232
|
+
PUT_UINT32( X3, output, 12 );
|
|
1233
|
+
}
|
|
1234
|
+
|