-
Notifications
You must be signed in to change notification settings - Fork 0
/
aes_enc.cpp
513 lines (394 loc) · 13.7 KB
/
aes_enc.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
/*Copyright (c) 2018, Jose Nunez-Yanez*/
/*University of Bristol. ENEAC project*/
#include "aes_enc.h"
void aes_wrapper_sw(uint8_t state[16],uint8_t cipher[16],uint8_t ekey[240]);
void aes_wrapper(data_t *state,data_t *cipher,uint8_t ekey[240],uint32_t byte_count);
void addroundkey(data_stream_t &state,uint8_t iteration, data_stream_t &result,uint8_t ekey[240],uint32_t byte_count);
void subbytes(data_stream_t &state, data_stream_t &result,uint32_t byte_count);
void mixcolumn(data_stream_t &state, data_stream_t &result,uint32_t byte_count);
void array2stream(data_t *state, data_stream_t &result, uint32_t byte_count);
void stream2array(data_stream_t &state, data_t *result, uint32_t byte_count);
void shift_row_enc_sw(uint8_t state[16], uint8_t result[16]);
void subbytes_sw(uint8_t state[16], uint8_t result[16]);
void addroundkey_sw(uint8_t state[16],uint8_t iteration, uint8_t result[16],uint8_t ekey[240]);
void mixcolumn_sw(uint8_t state[16], uint8_t result[16]);
void aes_enc_sw(uint8_t *state,uint8_t *cipher,uint8_t ekey[240],unsigned int block_size)
{
int i,j;
// uint8_t iteration = 0;
uint8_t x,y;
uint8_t state_buf[16];
uint8_t cipher_buf[16];
#pragma HLS array_partition variable=state_buf complete
#pragma HLS array_partition variable=cipher_buf complete
for(i=0;i<block_size;i+=16)
{
for(j=0; j<16; j++) {
state_buf[j] = *(state+i+j);
}
aes_wrapper_sw(state_buf,cipher_buf,ekey);
for(j=0; j<16; j++) {
*(cipher+i+j) = cipher_buf[j];
}
}
}
void aes_wrapper_sw(uint8_t state[16],uint8_t cipher[16],uint8_t ekey[240])
{
uint8_t sub[16];
uint8_t shift[16];
uint8_t mix[16];
uint8_t round[16];
addroundkey_sw(state,0,sub,ekey);
loop_main : for(int iteration = 1; iteration < nr; iteration++)
{
subbytes_sw(sub,shift);
shift_row_enc_sw(shift,mix);
mixcolumn_sw(mix,round);
addroundkey_sw(round,iteration,sub,ekey);
}
subbytes_sw(sub,shift);
shift_row_enc_sw(shift,round);
addroundkey_sw(round,nr,cipher,ekey);
}
//#pragma SDS data mem_attribute(cipher:PHYSICAL_CONTIGUOUS)
//#pragma SDS data mem_attribute(state:PHYSICAL_CONTIGUOUS)
#pragma SDS data data_mover(state:AXIDMA_SIMPLE, cipher:AXIDMA_SIMPLE)
#pragma SDS data copy(state[0:(block_size/16)])
#pragma SDS data copy(cipher[0:(block_size/16)])
#pragma SDS data access_pattern(state:SEQUENTIAL)
#pragma SDS data access_pattern(cipher:SEQUENTIAL)
void aes_enc(data_t *state,data_t *cipher,uint8_t ekey[240],unsigned int block_size)
{
int i,j;
uint8_t iteration = 0;
uint8_t x,y;
data_stream_t state_stream;
data_stream_t cipher_stream;
uint8_t ekey_buf[240];
#pragma HLS array_partition variable=ekey_buf complete
for(j=0; j<240; j++) {
#pragma HLS PIPELINE
ekey_buf[j] = ekey[j];
}
aes_wrapper(state,cipher,ekey_buf,block_size);
}
void aes_wrapper(data_t *state,data_t *cipher,uint8_t ekey[240],uint32_t byte_count)
{
data_stream_t state_stream;
#pragma HLS STREAM variable=state_stream depth=1
data_stream_t cipher_stream;
#pragma HLS STREAM variable=state_stream depth=1
data_stream_t inter0;
#pragma HLS STREAM variable=inter0 depth=1
data_stream_t inter1;
#pragma HLS STREAM variable=inter1 depth=1
data_stream_t inter2;
#pragma HLS STREAM variable=inter2 depth=1
data_stream_t inter3;
#pragma HLS STREAM variable=inter3 depth=1
data_stream_t inter4;
#pragma HLS STREAM variable=inter4 depth=1
data_stream_t inter5;
#pragma HLS STREAM variable=inter5 depth=1
data_stream_t inter6;
#pragma HLS STREAM variable=inter6 depth=1
data_stream_t inter7;
#pragma HLS STREAM variable=inter7 depth=1
data_stream_t inter8;
#pragma HLS STREAM variable=inter8 depth=1
data_stream_t inter9;
#pragma HLS STREAM variable=inter9 depth=1
data_stream_t inter10;
#pragma HLS STREAM variable=inter10 depth=1
data_stream_t inter11;
#pragma HLS STREAM variable=inter11 depth=1
data_stream_t inter12;
#pragma HLS STREAM variable=inter12 depth=1
data_stream_t inter13;
#pragma HLS STREAM variable=inter13 depth=1
data_stream_t inter14;
#pragma HLS STREAM variable=inter14 depth=1
data_stream_t inter15;
#pragma HLS STREAM variable=inter15 depth=1
data_stream_t inter16;
#pragma HLS STREAM variable=inter16 depth=1
data_stream_t inter17;
#pragma HLS STREAM variable=inter17 depth=1
data_stream_t inter18;
#pragma HLS STREAM variable=inter18 depth=1
data_stream_t inter19;
#pragma HLS STREAM variable=inter19 depth=1
data_stream_t inter20;
#pragma HLS STREAM variable=inter20 depth=1
data_stream_t inter21;
#pragma HLS STREAM variable=inter21 depth=1
data_stream_t inter22;
#pragma HLS STREAM variable=inter22 depth=1
data_stream_t inter23;
#pragma HLS STREAM variable=inter23 depth=1
data_stream_t inter24;
#pragma HLS STREAM variable=inter24 depth=1
data_stream_t inter25;
#pragma HLS STREAM variable=inter25 depth=1
data_stream_t inter26;
#pragma HLS STREAM variable=inter26 depth=1
data_stream_t inter27;
#pragma HLS STREAM variable=inter27 depth=1
data_stream_t inter28;
#pragma HLS STREAM variable=inter28 depth=1
data_stream_t inter29;
#pragma HLS STREAM variable=inter29 depth=1
data_stream_t inter30;
#pragma HLS STREAM variable=inter30 depth=1
data_stream_t inter31;
#pragma HLS STREAM variable=inter31 depth=1
data_stream_t inter32;
#pragma HLS STREAM variable=inter32 depth=1
data_stream_t inter33;
#pragma HLS STREAM variable=inter33 depth=1
data_stream_t inter34;
#pragma HLS STREAM variable=inter34 depth=1
data_stream_t inter35;
#pragma HLS STREAM variable=inter35 depth=1
data_stream_t inter36;
#pragma HLS STREAM variable=inter36 depth=1
data_stream_t inter37;
#pragma HLS STREAM variable=inter37 depth=1
data_stream_t inter38;
#pragma HLS STREAM variable=inter38 depth=1
data_stream_t inter39;
#pragma HLS STREAM variable=inter39 depth=1
data_stream_t inter40;
#pragma HLS STREAM variable=inter40 depth=1
#pragma HLS DATAFLOW
array2stream(state,state_stream,byte_count);
addroundkey(state_stream,0,inter0,ekey,byte_count);
subbytes(inter0,inter1,byte_count);
mixcolumn(inter1,inter2,byte_count);
addroundkey(inter2,1,inter3,ekey,byte_count);
subbytes(inter3,inter4,byte_count);
mixcolumn(inter4,inter5,byte_count);
addroundkey(inter5,2,inter6,ekey,byte_count);
subbytes(inter6,inter7,byte_count);
mixcolumn(inter7,inter8,byte_count);
addroundkey(inter8,3,inter9,ekey,byte_count);
subbytes(inter9,inter10,byte_count);
mixcolumn(inter10,inter11,byte_count);
addroundkey(inter11,4,inter12,ekey,byte_count);
subbytes(inter12,inter13,byte_count);
mixcolumn(inter13,inter14,byte_count);
addroundkey(inter14,5,inter15,ekey,byte_count);
subbytes(inter15,inter16,byte_count);
mixcolumn(inter16,inter17,byte_count);
addroundkey(inter17,6,inter18,ekey,byte_count);
subbytes(inter18,inter19,byte_count);
mixcolumn(inter19,inter20,byte_count);
addroundkey(inter20,7,inter21,ekey,byte_count);
subbytes(inter21,inter22,byte_count);
mixcolumn(inter22,inter23,byte_count);
addroundkey(inter23,8,inter24,ekey,byte_count);
subbytes(inter24,inter25,byte_count);
mixcolumn(inter25,inter26,byte_count);
addroundkey(inter26,9,inter27,ekey,byte_count);
subbytes(inter27,inter28,byte_count);
mixcolumn(inter28,inter29,byte_count);
addroundkey(inter29,10,inter30,ekey,byte_count);
subbytes(inter30,inter31,byte_count);
mixcolumn(inter31,inter32,byte_count);
addroundkey(inter32,11,inter33,ekey,byte_count);
subbytes(inter33,inter34,byte_count);
mixcolumn(inter34,inter35,byte_count);
addroundkey(inter35,12,inter36,ekey,byte_count);
subbytes(inter36,inter37,byte_count);
mixcolumn(inter37,inter38,byte_count);
addroundkey(inter38,13,inter39,ekey,byte_count);
subbytes(inter39,inter40,byte_count);
addroundkey(inter40,14,cipher_stream,ekey,byte_count);
stream2array(cipher_stream,cipher,byte_count);
}
void subbytes(data_stream_t &state, data_stream_t &result,uint32_t byte_count)
{
data_t state_temp,state_temp2;
uint8_t result_temp[16];
uint8_t state_array[16];
uint8_t x, y; //addresses the matrix
#pragma HLS array_partition variable=result_temp complete
#pragma HLS array_partition variable=state_array complete
for (unsigned int i = 0; i < byte_count/16; i++)
{
#pragma HLS loop_tripcount min=1 max=1024
state_temp = state.read();
for(unsigned int s=0;s<16;s++)
{
#pragma HLS unroll
state_array[s] = state_temp.range(s*8+7,s*8);
}
#pragma HLS PIPELINE II=INI_VAL
loop_sb1 : for(x=0;x<4;x++){
loop_sb2 : for(y=0;y<4;y++){
uint8_t state_byte = state_array[x*4+y];
result_temp[x*4+y] = sbox[state_byte];
}//end y loop
}//end x loop
//row_shift_enc
state_temp2.range(7,0) = result_temp[0];
state_temp2.range(15,8) = result_temp[1];
state_temp2.range(23,16) = result_temp[2];
state_temp2.range(31,24) = result_temp[3];
state_temp2.range(39,32) = result_temp[5];
state_temp2.range(47,40) = result_temp[6];
state_temp2.range(55,48) = result_temp[7];
state_temp2.range(63,56) = result_temp[4];
state_temp2.range(71,64) = result_temp[10];
state_temp2.range(87,80) = result_temp[8];
state_temp2.range(79,72) = result_temp[11];
state_temp2.range(95,88) = result_temp[9];
state_temp2.range(103,96) = result_temp[15];
state_temp2.range(127,120) = result_temp[14];
state_temp2.range(119,112) = result_temp[13];
state_temp2.range(111,104) = result_temp[12];
result.write(state_temp2);
}
}
void array2stream(data_t *state, data_stream_t &result, uint32_t byte_count)
{
for (unsigned int i = 0; i < byte_count/16; i++)
{
#pragma HLS loop_tripcount min=1 max=1024
#pragma HLS PIPELINE II=INI_VAL
data_t state_buf = *(state+i);
result.write(state_buf);
}
}
void stream2array(data_stream_t &state, data_t *result, uint32_t byte_count)
{
for (unsigned int i = 0; i < byte_count/16; i++)
{
#pragma HLS loop_tripcount min=1 max=1024
#pragma HLS PIPELINE II=INI_VAL
data_t result_buf = state.read();
*(result+i) = result_buf;
}
}
void addroundkey(data_stream_t &state, uint8_t iteration,data_stream_t &result,uint8_t ekey[240],uint32_t byte_count)
{
uint8_t result_array[16];
uint8_t state_array[16];
#pragma HLS array_partition variable=state_array complete
#pragma HLS array_partition variable=result_array complete
data_t result_temp;
data_t state_temp;
for (unsigned int i = 0; i < byte_count/16; i++)
{
#pragma HLS loop_tripcount min=1 max=1024
state_temp = state.read();
for(unsigned int s=0;s<16;s++)
{
#pragma HLS unroll
state_array[s] = state_temp(s*8+7,s*8);
}
unsigned int x,y;
#pragma HLS PIPELINE II=INI_VAL
loop_rk1 :for(x=0;x<4;x++) {
loop_rk2 : for(y=0;y<4;y++){
result_array[y+x*4] = state_array[y+x*4]^ ekey[iteration * nb * 4 + x * nb + y];
}
}
for(unsigned int s=0;s<16;s++)
{
#pragma HLS unroll
result_temp.range(s*8+7,s*8) = result_array[s];
}
result.write(result_temp);
}
}
void mixcolumn(data_stream_t &state,data_stream_t &result,uint32_t byte_count)
{
//B1 = (B1 * 2) XOR (B2 * 3) XOR (B3 * 1) XOR (B4 * 1)
//B2 = (B1 * 1) XOR (B2 * 2) XOR (B3 * 3) XOR (B4 * 1)
//B3 = (B1 * 1) XOR (B2 * 1) XOR (B3 * 2) XOR (B4 * 3)
//B4 = (B1 * 3) XOR (B2 * 1) XOR (B3 * 1) XOR (B4 * 2)
uint8_t x; // control of the column
uint8_t result_array[16];
uint8_t state_array[16];
#pragma HLS array_partition variable=state_array complete
#pragma HLS array_partition variable=result_array complete
data_t state_temp,result_temp;
for (unsigned int i = 0; i < byte_count/16; i++)
{
#pragma HLS loop_tripcount min=1 max=1024
state_temp = state.read();
for(unsigned int s=0;s<16;s++)
{
#pragma HLS unroll
state_array[s] = state_temp.range(s*8+7,s*8);
}
#pragma HLS PIPELINE II=INI_VAL
loop_mx1 :for(x=0;x<4;x++){
result_array[x] = (gf2[state_array[x]])^(gf3[state_array[4+x]])^(state_array[8+x])^(state_array[12+x]);
result_array[4+x] = (state_array[x])^(gf2[state_array[4+x]])^(gf3[state_array[8+x]])^(state_array[12+x]);
result_array[8+x] = (state_array[x])^(state_array[4+x])^(gf2[state_array[8+x]])^(gf3[state_array[12+x]]);
result_array[12+x] = (gf3[state_array[x]])^(state_array[4+x])^(state_array[8+x])^(gf2[state_array[12+x]]);
}
for(unsigned int s=0;s<16;s++)
{
#pragma HLS unroll
result_temp.range(s*8+7,s*8) = result_array[s];
}
result.write(result_temp);
}
}
void shift_row_enc_sw(uint8_t state[16], uint8_t result[16])
{
#pragma HLS PIPELINE
#pragma HLS array_partition variable=state complete
#pragma HLS array_partition variable=result complete
result[0] = state[0];
result[1] = state[1];
result[2] = state[2];
result[3] = state[3];
result[4] = state[5];
result[5] = state[6];
result[6] = state[7];
result[7] = state[4];
result[8] = state[10];
result[10] = state[8];
result[9] = state[11];
result[11] = state[9];
result[12] = state[15];
result[15] = state[14];
result[14] = state[13];
result[13] = state[12];
}
void subbytes_sw(uint8_t state[16], uint8_t result[16])
{
uint8_t x, y; //addresses the matrix
loop_sb1 : for(x=0;x<4;x++){
loop_sb2 : for(y=0;y<4;y++){
result[x*4+y] = sbox[state[x*4+y]];
}//end y loop
}//end x loop
}
void addroundkey_sw(uint8_t state[16], uint8_t iteration,uint8_t result[16],uint8_t ekey[240])
{
uint8_t x,y;
loop_rk1 :for(x=0;x<4;x++) {
loop_rk2 : for(y=0;y<4;y++){
result [y+x*4] = state [y+x*4] ^ ekey[iteration * nb * 4 + x * nb + y];
}
}
}
void mixcolumn_sw(uint8_t state[16],uint8_t result[16])
{
//B1 = (B1 * 2) XOR (B2 * 3) XOR (B3 * 1) XOR (B4 * 1)
//B2 = (B1 * 1) XOR (B2 * 2) XOR (B3 * 3) XOR (B4 * 1)
//B3 = (B1 * 1) XOR (B2 * 1) XOR (B3 * 2) XOR (B4 * 3)
//B4 = (B1 * 3) XOR (B2 * 1) XOR (B3 * 1) XOR (B4 * 2)
uint8_t x; // control of the column
loop_mx1 :for(x=0;x<4;x++){
result[x] = (gf2[state[x]])^(gf3[state[4+x]])^(state[8+x])^(state[12+x]);
result[4+x] = (state[x])^(gf2[state[4+x]])^(gf3[state[8+x]])^(state[12+x]);
result[8+x] = (state[x])^(state[4+x])^(gf2[state[8+x]])^(gf3[state[12+x]]);
result[12+x] = (gf3[state[x]])^(state[4+x])^(state[8+x])^(gf2[state[12+x]]);
}
}