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