aes.cpp revision 12855:588919e0e4aa
1#include <systemc.h>
2
3#define USE_TABLE 1
4
5#if DEBUG
6void
7Dump_R(char *s, sc_uint<8> X[4][4])
8{
9	printf("%s R\n", s);
10	for(int i = 0; i < 4; i++){
11		printf("|");
12		for(int j = 0; j < 4; j++){
13			printf("%02x|", (int)X[i][j]);
14		}
15		printf("\n");
16	}
17}
18
19void
20Dump_rk(char *s, sc_uint<8> X[11][4][4])
21{
22	printf("%s rk\n", s);
23	for(int i = 0; i < 11; i++){
24		printf("%2d: ", (int)i);
25		for(int j = 0; j < 4; j++){
26			printf("|");
27			for(int k = 0; k < 4; k++){
28				printf("%02x|", (int)X[i][j][k]);
29			}
30			printf("   ");
31		}
32		printf("\n");
33	}
34}
35#endif
36
37SC_MODULE(AES_Base)
38{
39	SC_CTOR(AES_Base) {}
40
41	void AddRoundKey(sc_uint<8> a[4][4], const sc_uint<8> rk[4][4]);
42	sc_uint<8> S_Table(sc_uint<8> a);
43	void SchedKey(sc_uint<8> k[4][4], sc_uint<8> W[11][4][4]);
44};
45
46sc_uint<8>
47AES_Base::S_Table(sc_uint<8> a)
48{
49	sc_uint<8> t;
50#if USE_TABLE
51	{
52	static sc_uint<8> S[256] = {
53 		99, 124, 119, 123, 242, 107, 111, 197,
54		48,   1, 103,  43, 254, 215, 171, 118,
55		202, 130, 201, 125, 250,  89,  71, 240,
56		173, 212, 162, 175, 156, 164, 114, 192,
57		183, 253, 147,  38,  54,  63, 247, 204,
58		52, 165, 229, 241, 113, 216,  49,  21,
59  		4, 199,  35, 195,  24, 150,   5, 154,
60		7,  18, 128, 226, 235,  39, 178, 117,
61  		9, 131,  44,  26,  27, 110,  90, 160,
62		82,  59, 214, 179,  41, 227,  47, 132,
63 		83, 209,   0, 237,  32, 252, 177,  91,
64		106, 203, 190,  57,  74,  76,  88, 207,
65		208, 239, 170, 251,  67,  77,  51, 133,
66		69, 249,   2, 127,  80,  60, 159, 168,
67 		81, 163,  64, 143, 146, 157,  56, 245,
68		188, 182, 218,  33,  16, 255, 243, 210,
69		205,  12,  19, 236,  95, 151,  68,  23,
70		196, 167, 126,  61, 100,  93,  25, 115,
71 		96, 129,  79, 220,  34,  42, 144, 136,
72		70, 238, 184,  20, 222,  94,  11, 219,
73		224,  50,  58,  10,  73,   6,  36,  92,
74		194, 211, 172,  98, 145, 149, 228, 121,
75		231, 200,  55, 109, 141, 213,  78, 169,
76		108,  86, 244, 234, 101, 122, 174,   8,
77		186, 120,  37,  46,  28, 166, 180, 198,
78		232, 221, 116,  31,  75, 189, 139, 138,
79		112,  62, 181, 102,  72,   3, 246,  14,
80		97,  53,  87, 185, 134, 193,  29, 158,
81		225, 248, 152,  17, 105, 217, 142, 148,
82		155,  30, 135, 233, 206,  85,  40, 223,
83		140, 161, 137,  13, 191, 230,  66, 104,
84		65, 153,  45,  15, 176,  84, 187,  22,
85	};
86	t = S[a];
87	}
88#else
89#define E(A,B) case A: t = B; break
90	switch(a){
91	E(  0, 99); E(  1,124); E(  2,119); E(  3,123); E(  4,242); E(  5,107);
92	E(  6,111); E(  7,197); E(  8, 48); E(  9,  1); E( 10,103); E( 11, 43);
93	E( 12,254); E( 13,215); E( 14,171); E( 15,118); E( 16,202); E( 17,130);
94	E( 18,201); E( 19,125); E( 20,250); E( 21, 89); E( 22, 71); E( 23,240);
95	E( 24,173); E( 25,212); E( 26,162); E( 27,175); E( 28,156); E( 29,164);
96	E( 30,114); E( 31,192); E( 32,183); E( 33,253); E( 34,147); E( 35, 38);
97	E( 36, 54); E( 37, 63); E( 38,247); E( 39,204); E( 40, 52); E( 41,165);
98	E( 42,229); E( 43,241); E( 44,113); E( 45,216); E( 46, 49); E( 47, 21);
99	E( 48,  4); E( 49,199); E( 50, 35); E( 51,195); E( 52, 24); E( 53,150);
100	E( 54,  5); E( 55,154); E( 56,  7); E( 57, 18); E( 58,128); E( 59,226);
101	E( 60,235); E( 61, 39); E( 62,178); E( 63,117); E( 64,  9); E( 65,131);
102	E( 66, 44); E( 67, 26); E( 68, 27); E( 69,110); E( 70, 90); E( 71,160);
103	E( 72, 82); E( 73, 59); E( 74,214); E( 75,179); E( 76, 41); E( 77,227);
104	E( 78, 47); E( 79,132); E( 80, 83); E( 81,209); E( 82,  0); E( 83,237);
105	E( 84, 32); E( 85,252); E( 86,177); E( 87, 91); E( 88,106); E( 89,203);
106	E( 90,190); E( 91, 57); E( 92, 74); E( 93, 76); E( 94, 88); E( 95,207);
107	E( 96,208); E( 97,239); E( 98,170); E( 99,251); E(100, 67); E(101, 77);
108	E(102, 51); E(103,133); E(104, 69); E(105,249); E(106,  2); E(107,127);
109	E(108, 80); E(109, 60); E(110,159); E(111,168); E(112, 81); E(113,163);
110	E(114, 64); E(115,143); E(116,146); E(117,157); E(118, 56); E(119,245);
111	E(120,188); E(121,182); E(122,218); E(123, 33); E(124, 16); E(125,255);
112	E(126,243); E(127,210); E(128,205); E(129, 12); E(130, 19); E(131,236);
113	E(132, 95); E(133,151); E(134, 68); E(135, 23); E(136,196); E(137,167);
114	E(138,126); E(139, 61); E(140,100); E(141, 93); E(142, 25); E(143,115);
115	E(144, 96); E(145,129); E(146, 79); E(147,220); E(148, 34); E(149, 42);
116	E(150,144); E(151,136); E(152, 70); E(153,238); E(154,184); E(155, 20);
117	E(156,222); E(157, 94); E(158, 11); E(159,219); E(160,224); E(161, 50);
118	E(162, 58); E(163, 10); E(164, 73); E(165,  6); E(166, 36); E(167, 92);
119	E(168,194); E(169,211); E(170,172); E(171, 98); E(172,145); E(173,149);
120	E(174,228); E(175,121); E(176,231); E(177,200); E(178, 55); E(179,109);
121	E(180,141); E(181,213); E(182, 78); E(183,169); E(184,108); E(185, 86);
122	E(186,244); E(187,234); E(188,101); E(189,122); E(190,174); E(191,  8);
123	E(192,186); E(193,120); E(194, 37); E(195, 46); E(196, 28); E(197,166);
124	E(198,180); E(199,198); E(200,232); E(201,221); E(202,116); E(203, 31);
125	E(204, 75); E(205,189); E(206,139); E(207,138); E(208,112); E(209, 62);
126	E(210,181); E(211,102); E(212, 72); E(213,  3); E(214,246); E(215, 14);
127	E(216, 97); E(217, 53); E(218, 87); E(219,185); E(220,134); E(221,193);
128	E(222, 29); E(223,158); E(224,225); E(225,248); E(226,152); E(227, 17);
129	E(228,105); E(229,217); E(230,142); E(231,148); E(232,155); E(233, 30);
130	E(234,135); E(235,233); E(236,206); E(237, 85); E(238, 40); E(239,223);
131	E(240,140); E(241,161); E(242,137); E(243, 13); E(244,191); E(245,230);
132	E(246, 66); E(247,104); E(248, 65); E(249,153); E(250, 45); E(251, 15);
133	E(252,176); E(253, 84); E(254,187); E(255, 22);
134	}
135#undef E
136#endif
137	return(t);
138}
139
140
141void
142AES_Base::AddRoundKey(sc_uint<8> a[4][4], const sc_uint<8> rk[4][4])
143{
144	for( sc_uint<3> i = 0; i < 4; i++){
145		for( sc_uint<3> j = 0; j < 4; j++){
146			a[i][j] = a[i][j] ^ rk[i][j];
147		}
148	}
149}
150
151void
152AES_Base::SchedKey(sc_uint<8> k[4][4], sc_uint<8> W[11][4][4])
153{
154	sc_uint<3> i, j;
155	sc_uint<8> tk[4][4];
156	sc_uint<8> tt;
157	sc_uint<4> t;
158
159	for(j = 0; j < 4; j++){
160		for(i = 0; i < 4; i++){
161			tk[i][j] = k[i][j];
162		}
163	}
164
165	for(j = 0; j < 4; j++){
166		for(i = 0; i < 4; i++){
167			W[0][i][j] = tk[i][j];
168		}
169	}
170
171	for( t = 1; t < 11; t++){
172		for(i = 0; i < 4; i++){
173			tk[i][0] ^= S_Table(tk[(i+1)&3][3]);
174		}
175
176#if USE_TABLE
177		{ static sc_uint<8> rcon[11] = {
178			0x0, /* dummy entry to lineup with t's value */
179  			0x01,
180			0x02,
181			0x04,
182			0x08,
183  			0x10,
184			0x20,
185			0x40,
186			0x80,
187  			0x1b,
188			0x36
189		};
190		tt = rcon[t];
191		}
192#else
193		switch(t){
194  		case  1: tt = 0x01; break; /* 0000 0001 */
195		case  2: tt = 0x02; break; /* 0000 0010 */
196		case  3: tt = 0x04; break; /* 0000 0100 */
197		case  4: tt = 0x08; break; /* 0000 1000 */
198  		case  5: tt = 0x10; break; /* 0001 0000 */
199		case  6: tt = 0x20; break; /* 0010 0000 */
200		case  7: tt = 0x40; break; /* 0100 0000 */
201		case  8: tt = 0x80; break; /* 1000 0000 */
202  		case  9: tt = 0x1b; break; /* 0001 1011 */
203		case 10: tt = 0x36; break; /* 0011 0110 */
204		}
205#endif
206
207		tk[0][0] ^= tt;
208
209		for(j = 1; j < 4; j++){
210			for(i = 0; i < 4; i++){
211				tk[i][j] ^= tk[i][j-1];
212			}
213		}
214
215		for(j = 0; j < 4; j++){
216			for(i = 0; i < 4; i++){
217				W[t][i][j] = tk[i][j];
218			}
219		}
220	}
221}
222
223class AES_Decrypt : public AES_Base {
224public:
225	SC_HAS_PROCESS(AES_Decrypt);
226	AES_Decrypt(sc_module_name name,
227		sc_clock& pCLK,
228		sc_signal<bool>& pRST_X,
229		sc_signal<bool>& pIn_req,
230		sc_signal<bool>& pIn_ack,
231		sc_signal<bool>& pIn_cmd,
232		sc_signal<sc_biguint<128> >& pIn_wire,
233		sc_signal<bool>& pOut_req,
234		sc_signal<bool>& pOut_ack,
235		sc_signal<sc_biguint<128> >& pOut_wire
236	) : AES_Base(name)
237	{
238	    CLK(pCLK); RST_X(pRST_X);
239	    In_req(pIn_req); In_ack(pIn_ack); In_cmd(pIn_cmd); In_wire(pIn_wire);
240	    Out_req(pOut_req); Out_ack(pOut_ack); Out_wire(pOut_wire);
241		SC_CTHREAD(MainThread, this->CLK.pos());
242		reset_signal_is(RST_X,false);
243	}
244
245	sc_in_clk CLK;
246	sc_in<bool> RST_X;
247
248	sc_in<sc_biguint<128> >  In_wire;
249	sc_out<bool>	      In_req;
250	sc_in<bool>	      In_ack;
251	sc_in<bool>	      In_cmd;
252
253	sc_out<sc_biguint<128> > Out_wire;
254	sc_in<bool>	      Out_req;
255	sc_out<bool>	      Out_ack;
256
257#define LOAD_KEY 0
258#define DECRYPT 1
259	sc_uint<1> cmd;
260
261	sc_uint<8> rk[11][4][4];
262	sc_uint<8> R[4][4];
263
264	void MainThread(void);
265	void Reset(void);
266
267	void Input(void);
268	void Output(void);
269
270	void Decrypt(void);
271
272	void InvMixColumns(sc_uint<8> a[4][4]);
273	void ShiftRows_Right_Rotate(sc_uint<8> a[4][4]);
274	void Substitution_Si(sc_uint<8> a[4][4]);
275	sc_uint<8> Si_Table(sc_uint<8> a);
276
277	sc_uint<8> dmul9(const sc_uint<8> B);
278	sc_uint<8> dmulb(const sc_uint<8> B);
279	sc_uint<8> dmuld(const sc_uint<8> B);
280	sc_uint<8> dmule(const sc_uint<8> B);
281};
282
283void
284AES_Decrypt::Reset(void)
285{
286	In_req = false;
287	Out_ack = false;
288}
289
290void
291AES_Decrypt::Input(void)
292{
293	sc_uint<8> t;
294	sc_biguint<128> t_In_wire;
295
296	(void)wait();
297	In_req = true;
298
299	do { wait(); } while(!In_ack);
300
301	cmd = In_cmd;
302	t_In_wire = In_wire.read();
303
304	/*
305	 * no matter whether it's a decrypt
306	 * or a key_schedule, get the input pins
307	 * into R[][].
308	 */
309	for(int i = 0; i < 4; i++){
310		for(int j = 0; j < 4; j++){
311			for( int k = 0; k < 8; k++){
312				t[k] = t_In_wire[(i*4+j)*8+k];
313			}
314			R[i][j] = t;
315		}
316	}
317
318	In_req = false;
319
320	//Dump_R("AES_Descrypt::Input R", R);
321}
322
323void
324AES_Decrypt::Output(void)
325{
326	sc_uint<8> t;
327	sc_biguint<128> t_Out_wire;
328
329	do { (void)wait(); } while(!Out_req);
330
331	/*
332	 * if it's a decrypt, drive R[][] onto output pins
333	 */
334	if( cmd == DECRYPT){
335		for(int i = 0; i < 4; i++){
336			for(int j = 0; j < 4; j++){
337				t = R[i][j];
338				for( int k = 0; k < 8; k++){
339					t_Out_wire[(i*4+j)*8+k] = t[k];
340				}
341			}
342		}
343		Out_wire.write(t_Out_wire);
344
345		//Dump_R("AES_Descrypt::Output R", R);
346	}
347
348	Out_ack = true;
349	(void)wait();
350	Out_ack = false;
351
352}
353
354void
355AES_Decrypt::MainThread(void)
356{
357	(void)Reset();
358
359	{
360	while(!RST_X)
361		(void)wait();
362	}
363
364	for(;;){
365		(void)Input();
366
367		if( cmd == LOAD_KEY ){
368			/*
369			 * take R[][] and expand
370			 * it into rk[][][]
371			 */
372			(void)SchedKey(R, rk);
373			(void)wait(3);
374
375			//Dump_rk("AES_Descrypt::MainThread rk", rk);
376		} else {
377			/*
378			 * take R[][] and rk[][][]
379			 * and decrypt the data inplace
380			 * into R[][]
381			 */
382			(void)Decrypt();
383			(void)wait(12);
384			(void)Output();
385		}
386
387	}
388}
389
390void
391AES_Decrypt::Decrypt(void)
392{
393	(void)AddRoundKey(R,rk[10]);
394	//Dump_R("10: AES_Decrypt::AddRoundKey", R);
395
396	(void)Substitution_Si(R);
397	//printf("%d: ", 10); Dump_R("AES_Decrypt::Substitution_Si", R);
398
399	(void)ShiftRows_Right_Rotate(R);
400	//printf("%d: ", 10); Dump_R("AES_Decrypt::ShiftRows_Right_Rotate", R);
401
402	for(sc_uint<4> i = 9; i > 0; i--){
403		(void)AddRoundKey(R, rk[i]);
404		//printf("%d: ", (int)i); Dump_R("AES_Decrypt::AddRoundKey", R);
405
406		(void)InvMixColumns(R);
407		//printf("%d: ", (int)i); Dump_R("AES_Decrypt::InvMixColums", R);
408
409		(void)Substitution_Si(R);
410		//printf("%d: ", (int)i); Dump_R("AES_Decrypt::Substitution_Si", R);
411
412		(void)ShiftRows_Right_Rotate(R);
413		//printf("%d: ", (int)i); Dump_R("AES_Decrypt::ShiftRows_Right_Rotate", R);
414	}
415
416	(void)AddRoundKey(R, rk[0]);
417	//Dump_R("0: AES_Decrypt::AddRoundKey", R);
418}
419
420sc_uint<8>
421AES_Decrypt::Si_Table(sc_uint<8> a)
422{
423	sc_uint<8> t;
424#if USE_TABLE
425	{
426	static sc_uint<8> Si[256] = {
427 		82,   9, 106, 213,  48,  54, 165,  56,
428		191,  64, 163, 158, 129, 243, 215, 251,
429		124, 227,  57, 130, 155,  47, 255, 135,
430		52, 142,  67,	68, 196, 222, 233, 203,
431 		84, 123, 148,	50, 166, 194,  35,  61,
432		238,  76, 149,	11,  66, 250, 195,  78,
433  		8,  46, 161, 102,  40, 217,  36, 178,
434		118,  91, 162,	73, 109, 139, 209,  37,
435		114, 248, 246, 100, 134, 104, 152,  22,
436		212, 164,  92, 204,  93, 101, 182, 146,
437		108, 112,  72,	80, 253, 237, 185, 218,
438		94,  21,  70,	87, 167, 141, 157, 132,
439		144, 216, 171,	 0, 140, 188, 211,  10,
440		247, 228,  88,	 5, 184, 179,  69,   6,
441		208,  44,  30, 143, 202,  63,  15,   2,
442		193, 175, 189,	 3,   1,  19, 138, 107,
443 		58, 145,  17,	65,  79, 103, 220, 234,
444		151, 242, 207, 206, 240, 180, 230, 115,
445		150, 172, 116,	34, 231, 173,  53, 133,
446		226, 249,  55, 232,  28, 117, 223, 110,
447 		71, 241,  26, 113,  29,  41, 197, 137,
448		111, 183,  98,	14, 170,  24, 190,  27,
449		252,  86,  62,	75, 198, 210, 121,  32,
450		154, 219, 192, 254, 120, 205,  90, 244,
451 		31, 221, 168,	51, 136,   7, 199,  49,
452		177,  18,  16,	89,  39, 128, 236,  95,
453 		96,  81, 127, 169,  25, 181,  74,  13,
454		45, 229, 122, 159, 147, 201, 156, 239,
455		160, 224,  59,	77, 174,  42, 245, 176,
456		200, 235, 187,	60, 131,  83, 153,  97,
457 		23,  43,   4, 126, 186, 119, 214,  38,
458		225, 105,  20,	99,  85,  33,  12, 125,
459	};
460	t = Si[a];
461	}
462#else
463#define E(A,B) case A: t = B; break
464	switch(a){
465	E(  0, 82); E(  1,  9); E(  2,106); E(  3,213); E(  4, 48); E(  5, 54);
466	E(  6,165); E(  7, 56); E(  8,191); E(  9, 64); E( 10,163); E( 11,158);
467	E( 12,129); E( 13,243); E( 14,215); E( 15,251); E( 16,124); E( 17,227);
468	E( 18, 57); E( 19,130); E( 20,155); E( 21, 47); E( 22,255); E( 23,135);
469	E( 24, 52); E( 25,142); E( 26, 67); E( 27, 68); E( 28,196); E( 29,222);
470	E( 30,233); E( 31,203); E( 32, 84); E( 33,123); E( 34,148); E( 35, 50);
471	E( 36,166); E( 37,194); E( 38, 35); E( 39, 61); E( 40,238); E( 41, 76);
472	E( 42,149); E( 43, 11); E( 44, 66); E( 45,250); E( 46,195); E( 47, 78);
473	E( 48,  8); E( 49, 46); E( 50,161); E( 51,102); E( 52, 40); E( 53,217);
474	E( 54, 36); E( 55,178); E( 56,118); E( 57, 91); E( 58,162); E( 59, 73);
475	E( 60,109); E( 61,139); E( 62,209); E( 63, 37); E( 64,114); E( 65,248);
476	E( 66,246); E( 67,100); E( 68,134); E( 69,104); E( 70,152); E( 71, 22);
477	E( 72,212); E( 73,164); E( 74, 92); E( 75,204); E( 76, 93); E( 77,101);
478	E( 78,182); E( 79,146); E( 80,108); E( 81,112); E( 82, 72); E( 83, 80);
479	E( 84,253); E( 85,237); E( 86,185); E( 87,218); E( 88, 94); E( 89, 21);
480	E( 90, 70); E( 91, 87); E( 92,167); E( 93,141); E( 94,157); E( 95,132);
481	E( 96,144); E( 97,216); E( 98,171); E( 99,  0); E(100,140); E(101,188);
482	E(102,211); E(103, 10); E(104,247); E(105,228); E(106, 88); E(107,  5);
483	E(108,184); E(109,179); E(110, 69); E(111,  6); E(112,208); E(113, 44);
484	E(114, 30); E(115,143); E(116,202); E(117, 63); E(118, 15); E(119,  2);
485	E(120,193); E(121,175); E(122,189); E(123,  3); E(124,  1); E(125, 19);
486	E(126,138); E(127,107); E(128, 58); E(129,145); E(130, 17); E(131, 65);
487	E(132, 79); E(133,103); E(134,220); E(135,234); E(136,151); E(137,242);
488	E(138,207); E(139,206); E(140,240); E(141,180); E(142,230); E(143,115);
489	E(144,150); E(145,172); E(146,116); E(147, 34); E(148,231); E(149,173);
490	E(150, 53); E(151,133); E(152,226); E(153,249); E(154, 55); E(155,232);
491	E(156, 28); E(157,117); E(158,223); E(159,110); E(160, 71); E(161,241);
492	E(162, 26); E(163,113); E(164, 29); E(165, 41); E(166,197); E(167,137);
493	E(168,111); E(169,183); E(170, 98); E(171, 14); E(172,170); E(173, 24);
494	E(174,190); E(175, 27); E(176,252); E(177, 86); E(178, 62); E(179, 75);
495	E(180,198); E(181,210); E(182,121); E(183, 32); E(184,154); E(185,219);
496	E(186,192); E(187,254); E(188,120); E(189,205); E(190, 90); E(191,244);
497	E(192, 31); E(193,221); E(194,168); E(195, 51); E(196,136); E(197,  7);
498	E(198,199); E(199, 49); E(200,177); E(201, 18); E(202, 16); E(203, 89);
499	E(204, 39); E(205,128); E(206,236); E(207, 95); E(208, 96); E(209, 81);
500	E(210,127); E(211,169); E(212, 25); E(213,181); E(214, 74); E(215, 13);
501	E(216, 45); E(217,229); E(218,122); E(219,159); E(220,147); E(221,201);
502	E(222,156); E(223,239); E(224,160); E(225,224); E(226, 59); E(227, 77);
503	E(228,174); E(229, 42); E(230,245); E(231,176); E(232,200); E(233,235);
504	E(234,187); E(235, 60); E(236,131); E(237, 83); E(238,153); E(239, 97);
505	E(240, 23); E(241, 43); E(242,  4); E(243,126); E(244,186); E(245,119);
506	E(246,214); E(247, 38); E(248,225); E(249,105); E(250, 20); E(251, 99);
507	E(252, 85); E(253, 33); E(254, 12); E(255,125);
508	}
509#undef E
510#endif
511	return(t);
512}
513void
514AES_Decrypt::Substitution_Si(sc_uint<8> a[4][4])
515{
516	for(sc_uint<3> j = 0; j < 4; j++){
517		for( sc_uint<3> i = 0; i < 4; i++){
518			a[i][j] = Si_Table(a[i][j]);
519		}
520	}
521}
522
523/*
524 * this routine does a rotate right
525 * on each row.  the first is rotated 0,
526 * ie, nothing is done.   the second row
527 * is roatated by 1, the third row by 2
528 * and the finally row by 3.
529 * ie:
530 *
531 *	row0	row1	row2	row3
532 *      0123    0123    0123    0123
533 *	||||    ||||    ||||    ||||
534 *	0123    3012    2301    1230
535 *
536 * this is equivalent to ShiftRows(1,...)
537 * code in the reference C code.   it
538 * has been expanded to get rid of the
539 * shifts[][][] array used at run time.
540 */
541void
542AES_Decrypt::ShiftRows_Right_Rotate(sc_uint<8> a[4][4])
543{
544	sc_uint<8> t;
545
546	t = a[1][3];
547	a[1][3] = a[1][2];
548	a[1][2] = a[1][1];
549	a[1][1] = a[1][0];
550	a[1][0] = t;
551
552	t = a[2][0];
553	a[2][0] = a[2][2];
554	a[2][2] = t;
555	t = a[2][1];
556	a[2][1] = a[2][3];
557	a[2][3] = t;
558
559	t = a[3][0];
560	a[3][0] = a[3][1];
561	a[3][1] = a[3][2];
562	a[3][2] = a[3][3];
563	a[3][3] = t;
564
565}
566
567void
568AES_Decrypt::InvMixColumns(sc_uint<8> a[4][4])
569{
570	sc_uint<8> t[4][4];
571
572	for(sc_uint<3> j = 0; j < 4; j++){
573		for( sc_uint<3> i = 0; i < 4; i++){
574			t[i][j] = dmule(a[i][j])
575			          ^ dmulb(a[(i + 1) & 3][j])
576			          ^ dmuld(a[(i + 2) & 3][j])
577			          ^ dmul9(a[(i + 3) & 3][j]);
578		}
579	}
580
581	for(sc_uint<3> j = 0; j < 4; j++){
582		for( sc_uint<3> i = 0; i < 4; i++){
583			a[i][j] = t[i][j];
584		}
585	}
586}
587
588sc_uint<8>
589AES_Decrypt::dmul9(const sc_uint<8> B)
590{
591	sc_uint<8> O;
592
593	O[0] = B[5]          ^B[0];
594	O[1] = B[5]^B[6]     ^B[1];
595	O[2] = B[6]^B[7]     ^B[2];
596	O[3] = B[0]^B[7]^B[5]^B[3];
597	O[4] = B[1]^B[6]^B[5]^B[4];
598	O[5] = B[7]^B[2]^B[6]^B[5];
599	O[6] = B[7]^B[3]     ^B[6];
600	O[7] = B[4]          ^B[7];
601
602	return(O);
603}
604
605sc_uint<8>
606AES_Decrypt::dmulb(const sc_uint<8> B)
607{
608	sc_uint<8> O;
609
610	O[0] = B[5]           ^B[7]      ^B[0];
611	O[1] = B[5]^B[6]      ^B[0]^B[7] ^B[1];
612	O[2] = B[6]^B[7]      ^B[1]      ^B[2];
613	O[3] = B[0]^B[5]      ^B[2]      ^B[3];
614	O[4] = B[1]^B[6]^B[5] ^B[3]^B[7] ^B[4];
615	O[5] = B[7]^B[2]^B[6] ^B[4]      ^B[5];
616	O[6] = B[7]^B[3]      ^B[5]      ^B[6];
617	O[7] = B[4]           ^B[6]      ^B[7];
618
619	return(O);
620}
621
622sc_uint<8>
623AES_Decrypt::dmuld(const sc_uint<8> B)
624{
625	sc_uint<8> O;
626
627	O[0] = B[5]           ^B[6]      ^B[0];
628	O[1] = B[5]           ^B[7]      ^B[1];
629	O[2] = B[6]           ^B[0]      ^B[2];
630	O[3] = B[0]^B[7]^B[5] ^B[1]^B[6] ^B[3];
631	O[4] = B[1]^B[5]      ^B[2]^B[7] ^B[4];
632	O[5] = B[2]^B[6]      ^B[3]      ^B[5];
633	O[6] = B[7]^B[3]      ^B[4]      ^B[6];
634	O[7] = B[4]           ^B[5]      ^B[7];
635
636	return(O);
637}
638
639sc_uint<8>
640AES_Decrypt::dmule(const sc_uint<8> B)
641{
642	sc_uint<8> O;
643
644	O[0] = B[5]           ^B[6]      ^B[7];
645	O[1] = B[5]           ^B[7]      ^B[0]^B[7];
646	O[2] = B[6]           ^B[0]      ^B[1];
647	O[3] = B[0]^B[7]^B[5] ^B[1]^B[6] ^B[2]^B[7];
648	O[4] = B[1]^B[5]      ^B[2]^B[7] ^B[3]^B[7];
649	O[5] = B[2]^B[6]      ^B[3]      ^B[4];
650	O[6] = B[7]^B[3]      ^B[4]      ^B[5];
651	O[7] = B[4]           ^B[5]      ^B[6];
652
653	return(O);
654}
655
656class AES_Encrypt : public AES_Base {
657public:
658	SC_HAS_PROCESS(AES_Encrypt);
659	AES_Encrypt(sc_module_name name,
660		    sc_clock& pCLK,
661		    sc_signal<bool>& pRST_X,
662		    sc_signal<bool>& pIn_req,
663		    sc_signal<bool>& pIn_ack,
664		    sc_signal<bool>& pIn_cmd,
665		    sc_signal<sc_biguint<128> >& pIn_wire,
666		    sc_signal<bool>& pOut_req,
667		    sc_signal<bool>& pOut_ack,
668		    sc_signal<sc_biguint<128> >& pOut_wire
669	) : AES_Base(name)
670	{
671	    CLK(pCLK); RST_X(pRST_X);
672	    In_req(pIn_req); In_ack(pIn_ack); In_cmd(pIn_cmd); In_wire(pIn_wire);
673	    Out_req(pOut_req); Out_ack(pOut_ack); Out_wire(pOut_wire);
674		SC_CTHREAD(MainThread, this->CLK.pos());
675		reset_signal_is(RST_X,false);
676	}
677
678	sc_in_clk CLK;
679	sc_in<bool> RST_X;
680
681	sc_in<sc_biguint<128> >  In_wire;
682	sc_out<bool>	      In_req;
683	sc_in<bool>	      In_ack;
684	sc_in<bool>	      In_cmd;
685
686	sc_out<sc_biguint<128> > Out_wire;
687	sc_in<bool>	      Out_req;
688	sc_out<bool>	      Out_ack;
689
690#define LOAD_KEY 0
691#define ENCRYPT 1
692	sc_uint<1> cmd;
693	sc_uint<8> rk[11][4][4];
694	sc_uint<8> R[4][4];
695
696	void MainThread(void);
697	void Reset(void);
698
699	void Input(void);
700	void Output(void);
701
702	void Encrypt(void);
703
704	void MixColumns(sc_uint<8> a[4][4]);
705	void ShiftRows_Left_Rotate(sc_uint<8> a[4][4]);
706	void Substitution_S(sc_uint<8> a[4][4]);
707
708	sc_uint<8> dmul2(const sc_uint<8> B);
709	sc_uint<8> dmul3(const sc_uint<8> B);
710};
711
712
713void
714AES_Encrypt::Reset(void)
715{
716	In_req = false;
717	Out_ack = false;
718}
719
720void
721AES_Encrypt::Input(void)
722{
723	sc_biguint<128> t_In_wire;
724	sc_uint<8> t;
725
726	(void)wait();
727	In_req = true;
728
729	do { wait(); } while(!In_ack);
730
731	cmd = In_cmd;
732	t_In_wire = In_wire.read();
733
734	/*
735	 * no matter whether it's a decrypt
736	 * or a key_schedule, get the input pins
737	 * into R[][].
738	 */
739	for(int i = 0; i < 4; i++){
740		for(int j = 0; j < 4; j++){
741			for( int k = 0; k < 8; k++){
742				t[k] = t_In_wire[(i*4+j)*8+k];
743			}
744			R[i][j] = t;
745		}
746	}
747
748	In_req = false;
749
750	//Dump_R("AES_Encrypt::Input R", R);
751}
752
753void
754AES_Encrypt::Output(void)
755{
756	sc_biguint<128> t_Out_wire;
757	sc_uint<8> t;
758
759	do { (void)wait(); } while(!Out_req);
760
761	/*
762	 * if it's a encrypt, drive R[][] onto output pins
763	 */
764	if( cmd == ENCRYPT){
765		for(int i = 0; i < 4; i++){
766			for(int j = 0; j < 4; j++){
767				t = R[i][j];
768				for( int k = 0; k < 8; k++){
769					t_Out_wire[(i*4+j)*8+k] = t[k];
770				}
771			}
772		}
773
774		(void)Out_wire.write(t_Out_wire);
775
776		//Dump_R("AES_Encrypt::Output R", R);
777	}
778
779	Out_ack = true;
780	wait();
781	Out_ack = false;
782
783}
784
785void
786AES_Encrypt::MainThread(void)
787{
788	(void)Reset();
789
790	{
791	while(!RST_X)
792		(void)wait();
793	}
794
795	for(;;){
796		(void)Input();
797
798		if( cmd == LOAD_KEY){
799			/*
800			 * take R[][] and expand
801			 * it into rk[][][]
802			 */
803			(void)SchedKey(R, rk);
804			(void)wait(3);
805			//Dump_rk("AES_Encrypt::MainThread rk", rk);
806		} else {
807			/*
808			 * take R[][] and rk[][][]
809			 * and encrypt the data inplace
810			 * into R[][]
811			 */
812			(void)Encrypt();
813			(void)wait(12);
814			(void)Output();
815		}
816	}
817}
818
819void
820AES_Encrypt::Encrypt(void)
821{
822	(void)AddRoundKey(R, rk[0]);
823	//Dump_R("0: AES_Encrypt::AddRoundKey", R);
824
825	for(sc_uint<4> i = 1; i < 10; i++){
826		(void)Substitution_S(R);
827		//printf("%d: ", (int)i); Dump_R("AES_Encrypt::Substitution_S", R);
828
829		(void)ShiftRows_Left_Rotate(R);
830		//printf("%d: ", (int)i); Dump_R("AES_Encrypt::ShiftRows_Left_Rotate", R);
831
832		(void)MixColumns(R);
833		//printf("%d: ", (int)i); Dump_R("AES_Encrypt::MixColums", R);
834
835		(void)AddRoundKey(R, rk[i]);
836		//printf("%d: ", (int)i); Dump_R("AES_Encrypt::AddRoundKey", R);
837	}
838
839	(void)Substitution_S(R);
840	//printf("%d: ", 10); Dump_R("AES_Encrypt::Substitution_S", R);
841
842	(void)ShiftRows_Left_Rotate(R);
843	//printf("%d: ", 10); Dump_R("AES_Encrypt::ShiftRows_Left_Rotate", R);
844
845	(void)AddRoundKey(R,rk[10]);
846	//printf("%d: ", 10); Dump_R("AES_Encrypt::AddRoundKey", R);
847}
848
849
850void
851AES_Encrypt::Substitution_S(sc_uint<8> a[4][4])
852{
853	for(sc_uint<3> j = 0; j < 4; j++){
854		for( sc_uint<3> i = 0; i < 4; i++){
855			a[i][j] = S_Table(a[i][j]);
856		}
857	}
858}
859
860/*
861 * this routine does a rotate left
862 * on each row.  the first is rotated 0,
863 * ie, nothing is done.   the second row
864 * is roatated by 1, the third row by 2
865 * and the finally row by 3.
866 * ie:
867 *
868 *	row0	row1	row2	row3
869 *      0123    0123    0123    0123
870 *	||||    ||||    ||||    ||||
871 *	0123    1230    2301    3012
872 *
873 * this is equivalent to ShiftRows(0,...)
874 * code in the reference C code.   it
875 * has been expanded to get rid of the
876 * shifts[][][] array used at run time.
877 */
878void
879AES_Encrypt::ShiftRows_Left_Rotate(sc_uint<8> a[4][4])
880{
881	sc_uint<8> t;
882
883	t = a[1][0];
884	a[1][0] = a[1][1];
885	a[1][1] = a[1][2];
886	a[1][2] = a[1][3];
887	a[1][3] = t;
888
889	t = a[2][0];
890	a[2][0] = a[2][2];
891	a[2][2] = t;
892	t = a[2][1];
893	a[2][1] = a[2][3];
894	a[2][3] = t;
895
896	t = a[3][3];
897	a[3][3] = a[3][2];
898	a[3][2] = a[3][1];
899	a[3][1] = a[3][0];
900	a[3][0] = t;
901}
902
903void
904AES_Encrypt::MixColumns(sc_uint<8> a[4][4])
905{
906	sc_uint<8> t[4][4];
907
908	for(sc_uint<3> j = 0; j < 4; j++){
909		for( sc_uint<3> i = 0; i < 4; i++){
910			t[i][j] = dmul2(a[i][j])
911                                ^ dmul3(a[(i + 1) & 3][j])
912                                ^ a[(i + 2) & 3][j]
913                                ^ a[(i + 3) & 3][j];
914
915		}
916	}
917
918	for(sc_uint<3> j = 0; j < 4; j++){
919		for( sc_uint<3> i = 0; i < 4; i++){
920			a[i][j] = t[i][j];
921		}
922	}
923}
924
925
926
927sc_uint<8>
928AES_Encrypt::dmul2(const sc_uint<8> B)
929{
930	sc_uint<8> O;
931
932	O[0] = B[7];
933	O[1] = B[0]^B[7];
934	O[2] = B[1];
935	O[3] = B[2]^B[7];
936	O[4] = B[3]^B[7];
937	O[5] = B[4];
938	O[6] = B[5];
939	O[7] = B[6];
940
941	return(O);
942}
943
944sc_uint<8>
945AES_Encrypt::dmul3(const sc_uint<8> B)
946{
947	sc_uint<8> O;
948
949	O[0] = B[7]     ^B[0];
950	O[1] = B[0]^B[7]^B[1];
951	O[2] = B[1]     ^B[2];
952	O[3] = B[2]^B[7]^B[3];
953	O[4] = B[3]^B[7]^B[4];
954	O[5] = B[4]     ^B[5];
955	O[6] = B[5]     ^B[6];
956	O[7] = B[6]     ^B[7];
957
958	return(O);
959}
960
961#define TESTBENCH 1
962#if TESTBENCH
963
964sc_biguint<128>
965str2biguint(char *s)
966{
967	static sc_biguint<128> a;
968	char str[16];
969	int i, c;
970
971	for(i = 0; i < 16 && *s != '\0'; i++, s++)
972		str[i] = *s;
973
974	while( i < 16)
975		str[i++] = ' ';
976
977	for(i = 0; i < 16; i++){
978		c = str[i];
979		a[(i*8)+0] = (c&1);
980		a[(i*8)+1] = ((c>>1)&1);
981		a[(i*8)+2] = ((c>>2)&1);
982		a[(i*8)+3] = ((c>>3)&1);
983		a[(i*8)+4] = ((c>>4)&1);
984		a[(i*8)+5] = ((c>>5)&1);
985		a[(i*8)+6] = ((c>>6)&1);
986		a[(i*8)+7] = ((c>>7)&1);
987	}
988
989	return(a);
990}
991
992char *
993biguint2str(sc_biguint<128> a)
994{
995	static char str[17];
996	int i;
997	char c;
998
999	str[16] = '\0';
1000
1001	for( i = 0; i < 128; i += 8){
1002		c = 0;
1003		c |= a[i+0] ? 1 : 0;
1004		c |= a[i+1] ? 1<<1 : 0;
1005		c |= a[i+2] ? 1<<2 : 0;
1006		c |= a[i+3] ? 1<<3 : 0;
1007		c |= a[i+4] ? 1<<4 : 0;
1008		c |= a[i+5] ? 1<<5 : 0;
1009		c |= a[i+6] ? 1<<6 : 0;
1010		c |= a[i+7] ? 1<<7 : 0;
1011		str[i/8] = c;
1012
1013	}
1014
1015	return(&str[0]);
1016}
1017
1018sc_biguint<128>
1019makekey(char *keyMaterial)
1020{
1021	int i, j, t, k;
1022	sc_uint<8> R[4][4];
1023	sc_uint<8> tt;
1024	sc_biguint<128> key;
1025
1026	for(i = 0; i < 128/8; i++) {
1027		t = keyMaterial[2*i];
1028		if ((t >= '0') && (t <= '9')) j = (t - '0') << 4;
1029		else if ((t >= 'a') && (t <= 'f')) j = (t - 'a' + 10) << 4;
1030		else if ((t >= 'A') && (t <= 'F')) j = (t - 'A' + 10) << 4;
1031		else abort();
1032
1033		t = keyMaterial[2*i+1];
1034		if ((t >= '0') && (t <= '9')) j ^= (t - '0');
1035		else if ((t >= 'a') && (t <= 'f')) j ^= (t - 'a' + 10);
1036		else if ((t >= 'A') && (t <= 'F')) j ^= (t - 'A' + 10);
1037		else abort();
1038
1039		R[i % 4][i / 4] = j;
1040	}
1041
1042	for(i = 0; i < 4; i++){
1043		for(j = 0; j < 4; j++){
1044			tt = R[i][j];
1045			for(k = 0; k < 8; k++){
1046				key[(i*4+j)*8+k] = tt[k];
1047			}
1048		}
1049	}
1050	return(key);
1051}
1052
1053
1054int
1055sc_main(int argc, char *argv[])
1056{
1057	sc_clock clock;
1058	sc_signal<bool> reset;
1059	sc_signal<bool> D_In_req;
1060	sc_signal<bool> D_In_ack;
1061	sc_signal<bool> D_In_cmd;
1062	sc_signal<bool> D_Out_req;
1063	sc_signal<bool> D_Out_ack;
1064	sc_signal<sc_biguint<128> > D_In_wire;
1065	sc_signal<sc_biguint<128> > D_Out_wire;
1066	sc_signal<bool> E_In_req;
1067	sc_signal<bool> E_In_ack;
1068	sc_signal<bool> E_In_cmd;
1069	sc_signal<bool> E_Out_req;
1070	sc_signal<bool> E_Out_ack;
1071	sc_signal<sc_biguint<128> > E_In_wire;
1072	sc_signal<sc_biguint<128> > E_Out_wire;
1073	sc_biguint<128> key;
1074	sc_biguint<128> t;
1075	char *s;
1076	char key_string[33] = "deadbeef0123456776543210beefdead";
1077	char in[17] = "abcdefghijklmnop";
1078	char *out;
1079	bool err;
1080	int i;
1081
1082	AES_Encrypt E("AES_Encrypt",
1083		clock,
1084		reset,
1085		E_In_req,
1086		E_In_ack,
1087		E_In_cmd,
1088		E_In_wire,
1089		E_Out_req,
1090		E_Out_ack,
1091		E_Out_wire);
1092
1093	AES_Decrypt D("AES_Decrypt",
1094		clock,
1095		reset,
1096		D_In_req,
1097		D_In_ack,
1098		D_In_cmd,
1099		D_In_wire,
1100		D_Out_req,
1101		D_Out_ack,
1102		D_Out_wire);
1103
1104
1105	key = makekey(key_string);
1106
1107	reset = 0;
1108	sc_start(2, SC_NS);
1109	reset = 1;
1110	sc_start(2, SC_NS);
1111
1112	while( !E_In_req) sc_start(1, SC_NS);
1113	E_In_cmd = LOAD_KEY;
1114	E_In_ack = 1;
1115	E_In_wire = key;
1116	do { sc_start(1, SC_NS); E_In_ack = 0; } while( !E_In_req);
1117
1118	while( !D_In_req) sc_start(1, SC_NS);
1119	D_In_cmd = LOAD_KEY;
1120	D_In_ack = 1;
1121	D_In_wire = key;
1122	do { sc_start(1, SC_NS); D_In_ack = 0; } while( !D_In_req);
1123
1124
1125	while( !E_In_req) sc_start(1, SC_NS);
1126	E_Out_req = 1;
1127	E_In_cmd = ENCRYPT;
1128	E_In_ack = 1;
1129	E_In_wire = str2biguint((char*)"abcdefghijklmnop");
1130	do { sc_start(1, SC_NS); E_In_ack = 0; } while(!E_Out_ack);
1131	E_Out_req = 0;
1132	sc_start(1, SC_NS);
1133
1134	while( !D_In_req) sc_start(1, SC_NS);
1135	D_Out_req = 1;
1136	D_In_cmd = DECRYPT;
1137	D_In_ack = 1;
1138	D_In_wire = E_Out_wire;
1139	do { sc_start(1, SC_NS); D_In_ack = 0; } while(!D_Out_ack);
1140	out = biguint2str(D_Out_wire);
1141	D_Out_req = 0;
1142	sc_start(1, SC_NS);
1143
1144	err = false;
1145	for(i = 0; i < 16; i++){
1146		if( in[i] != out[i]){
1147			err = true;
1148			break;
1149		}
1150	}
1151
1152	if( err){
1153		cout << "mismatch error at index " << i << endl;
1154		cout << "key:" << key_string << " in:" << in
1155                     << " out:" << out << endl;
1156	} else {
1157		cout << "program complete" << endl;
1158	}
1159
1160	return(0);
1161}
1162#endif
1163
1164
1165