Advertisement
Stiepen

Broken AESlua cc port

Mar 14th, 2013
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 17.92 KB | None | 0 0
  1. include("bit");
  2.  
  3. include("aeslua/gf");
  4. include("aeslua/util");
  5. local gf, util = aeslua.gf, aeslua.util
  6.  
  7. --
  8. -- Implementation of AES with nearly pure lua (only bitlib is needed)
  9. --
  10. -- AES with lua is slow, really slow :-)
  11. --
  12.  
  13. local public = {};
  14. local private = {};
  15.  
  16. aeslua.aes = public;
  17.  
  18. -- some constants
  19. public.ROUNDS = "rounds";
  20. public.KEY_TYPE = "type";
  21. public.ENCRYPTION_KEY=1;
  22. public.DECRYPTION_KEY=2;
  23.  
  24. -- aes SBOX
  25. private.SBox = {};
  26. private.iSBox = {};
  27.  
  28. -- aes tables
  29. private.table0 = {};
  30. private.table1 = {};
  31. private.table2 = {};
  32. private.table3 = {};
  33.  
  34. private.tableInv0 = {};
  35. private.tableInv1 = {};
  36. private.tableInv2 = {};
  37. private.tableInv3 = {};
  38.  
  39. -- round constants
  40. private.rCon = {0x01000000,
  41.                 0x02000000,
  42.                 0x04000000,
  43.                 0x08000000,
  44.                 0x10000000,
  45.                 0x20000000,
  46.                 0x40000000,
  47.                 0x80000000,
  48.                 0x1b000000,
  49.                 0x36000000,
  50.                 0x6c000000,
  51.                 0xd8000000,
  52.                 0xab000000,
  53.                 0x4d000000,
  54.                 0x9a000000,
  55.                 0x2f000000};
  56.  
  57. --
  58. -- affine transformation for calculating the S-Box of AES
  59. --
  60. function private.affinMap(byte)
  61.     mask = 0xf8;
  62.     result = 0;
  63.     for i = 1,8 do
  64.         result = bit.blshift(result,1);
  65.  
  66.         parity = util.byteParity(bit.band(byte,mask));
  67.         result = result + parity
  68.  
  69.         -- simulate roll
  70.         lastbit = bit.band(mask, 1);
  71.         mask = bit.band(bit.brshift(mask, 1),0xff);
  72.         if (lastbit ~= 0) then
  73.             mask = bit.bor(mask, 0x80);
  74.         else
  75.             mask = bit.band(mask, 0x7f);
  76.         end
  77.     end
  78.  
  79.     return bit.bxor(result, 0x63);
  80. end
  81.  
  82. --
  83. -- calculate S-Box and inverse S-Box of AES
  84. -- apply affine transformation to inverse in finite field 2^8
  85. --
  86. function private.calcSBox()
  87.     for i = 0, 255 do
  88.     if (i ~= 0) then
  89.         inverse = gf.invert(i);
  90.     else
  91.         inverse = i;
  92.     end
  93.         mapped = private.affinMap(inverse);                
  94.         private.SBox[i] = mapped;
  95.         private.iSBox[mapped] = i;
  96.     end
  97. end
  98.  
  99. --
  100. -- Calculate round tables
  101. -- round tables are used to calculate shiftRow, MixColumn and SubBytes
  102. -- with 4 table lookups and 4 xor operations.
  103. --
  104. function private.calcRoundTables()
  105.     for x = 0,255 do
  106.         byte = private.SBox[x];
  107.         private.table0[x] = util.putByte(gf.mul(0x03, byte), 0)
  108.                           + util.putByte(             byte , 1)
  109.                           + util.putByte(             byte , 2)
  110.                           + util.putByte(gf.mul(0x02, byte), 3);
  111.         private.table1[x] = util.putByte(             byte , 0)
  112.                           + util.putByte(             byte , 1)
  113.                           + util.putByte(gf.mul(0x02, byte), 2)
  114.                           + util.putByte(gf.mul(0x03, byte), 3);
  115.         private.table2[x] = util.putByte(             byte , 0)
  116.                           + util.putByte(gf.mul(0x02, byte), 1)
  117.                           + util.putByte(gf.mul(0x03, byte), 2)
  118.                           + util.putByte(             byte , 3);
  119.         private.table3[x] = util.putByte(gf.mul(0x02, byte), 0)
  120.                           + util.putByte(gf.mul(0x03, byte), 1)
  121.                           + util.putByte(             byte , 2)
  122.                           + util.putByte(             byte , 3);
  123.     end
  124. end
  125.  
  126. --
  127. -- Calculate inverse round tables
  128. -- does the inverse of the normal roundtables for the equivalent
  129. -- decryption algorithm.
  130. --
  131. function private.calcInvRoundTables()
  132.     for x = 0,255 do
  133.         byte = private.iSBox[x];
  134.         private.tableInv0[x] = util.putByte(gf.mul(0x0b, byte), 0)
  135.                              + util.putByte(gf.mul(0x0d, byte), 1)
  136.                              + util.putByte(gf.mul(0x09, byte), 2)
  137.                              + util.putByte(gf.mul(0x0e, byte), 3);
  138.         private.tableInv1[x] = util.putByte(gf.mul(0x0d, byte), 0)
  139.                              + util.putByte(gf.mul(0x09, byte), 1)
  140.                              + util.putByte(gf.mul(0x0e, byte), 2)
  141.                              + util.putByte(gf.mul(0x0b, byte), 3);
  142.         private.tableInv2[x] = util.putByte(gf.mul(0x09, byte), 0)
  143.                              + util.putByte(gf.mul(0x0e, byte), 1)
  144.                              + util.putByte(gf.mul(0x0b, byte), 2)
  145.                              + util.putByte(gf.mul(0x0d, byte), 3);
  146.         private.tableInv3[x] = util.putByte(gf.mul(0x0e, byte), 0)
  147.                              + util.putByte(gf.mul(0x0b, byte), 1)
  148.                              + util.putByte(gf.mul(0x0d, byte), 2)
  149.                              + util.putByte(gf.mul(0x09, byte), 3);
  150.     end
  151. end
  152.  
  153.  
  154. --
  155. -- rotate word: 0xaabbccdd gets 0xbbccddaa
  156. -- used for key schedule
  157. --
  158. function private.rotWord(word)
  159.     local tmp = bit.band(word,0xff000000);
  160.     return (bit.blshift(word,8) + bit.brshift(tmp,24)) ;
  161. end
  162.  
  163. --
  164. -- replace all bytes in a word with the SBox.
  165. -- used for key schedule
  166. --
  167. function private.subWord(word)
  168.     return util.putByte(private.SBox[util.getByte(word,0)],0)
  169.          + util.putByte(private.SBox[util.getByte(word,1)],1)
  170.          + util.putByte(private.SBox[util.getByte(word,2)],2)
  171.          + util.putByte(private.SBox[util.getByte(word,3)],3);
  172. end
  173.  
  174. --
  175. -- generate key schedule for aes encryption
  176. --
  177. -- returns table with all round keys and
  178. -- the necessary number of rounds saved in [public.ROUNDS]
  179. --
  180. function public.expandEncryptionKey(key)
  181.     local keySchedule = {};
  182.     local keyWords = math.floor(#key / 4);
  183.    
  184.  
  185.     if ((keyWords ~= 4 and keyWords ~= 6 and keyWords ~= 8) or (keyWords * 4 ~= #key)) then
  186.         print("Invalid key size: ", keyWords);
  187.         return nil;
  188.     end
  189.  
  190.     keySchedule[public.ROUNDS] = keyWords + 6;
  191.     keySchedule[public.KEY_TYPE] = public.ENCRYPTION_KEY;
  192.  
  193.     for i = 0,keyWords - 1 do
  194.         keySchedule[i] = util.putByte(key[i*4+1], 3)
  195.                        + util.putByte(key[i*4+2], 2)
  196.                        + util.putByte(key[i*4+3], 1)
  197.                        + util.putByte(key[i*4+4], 0);  
  198.     end    
  199.    
  200.     for i = keyWords, (keySchedule[public.ROUNDS] + 1)*4 - 1 do
  201.         local tmp = keySchedule[i-1];
  202.  
  203.         if ( i % keyWords == 0) then
  204.             tmp = private.rotWord(tmp);
  205.             tmp = private.subWord(tmp);
  206.            
  207.             local index = math.floor(i/keyWords);
  208.             tmp = bit.bxor(tmp,private.rCon[index]);
  209.         elseif (keyWords > 6 and i % keyWords == 4) then
  210.             tmp = private.subWord(tmp);
  211.         end
  212.        
  213.         keySchedule[i] = bit.bxor(keySchedule[(i-keyWords)],tmp);
  214.     end
  215.  
  216.     return keySchedule;
  217. end
  218.  
  219. --
  220. -- Inverse mix column
  221. -- used for key schedule of decryption key
  222. --
  223. function private.invMixColumnOld(word)
  224.     local b0 = util.getByte(word,3);
  225.     local b1 = util.getByte(word,2);
  226.     local b2 = util.getByte(word,1);
  227.     local b3 = util.getByte(word,0);
  228.      
  229.     return util.putByte(gf.add(gf.add(gf.add(gf.mul(0x0b, b1),
  230.                                              gf.mul(0x0d, b2)),
  231.                                              gf.mul(0x09, b3)),
  232.                                              gf.mul(0x0e, b0)),3)
  233.          + util.putByte(gf.add(gf.add(gf.add(gf.mul(0x0b, b2),
  234.                                              gf.mul(0x0d, b3)),
  235.                                              gf.mul(0x09, b0)),
  236.                                              gf.mul(0x0e, b1)),2)
  237.          + util.putByte(gf.add(gf.add(gf.add(gf.mul(0x0b, b3),
  238.                                              gf.mul(0x0d, b0)),
  239.                                              gf.mul(0x09, b1)),
  240.                                              gf.mul(0x0e, b2)),1)
  241.          + util.putByte(gf.add(gf.add(gf.add(gf.mul(0x0b, b0),
  242.                                              gf.mul(0x0d, b1)),
  243.                                              gf.mul(0x09, b2)),
  244.                                              gf.mul(0x0e, b3)),0);
  245. end
  246.  
  247. --
  248. -- Optimized inverse mix column
  249. -- look at http://fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.311.pdf
  250. -- TODO: make it work
  251. --
  252. function private.invMixColumn(word)
  253.     local b0 = util.getByte(word,3);
  254.     local b1 = util.getByte(word,2);
  255.     local b2 = util.getByte(word,1);
  256.     local b3 = util.getByte(word,0);
  257.    
  258.     local t = bit.bxor(b3,b2);
  259.     local u = bit.bxor(b1,b0);
  260.     local v = bit.bxor(t,u);
  261.     v = bit.bxor(v,gf.mul(0x08,v));
  262.     w = bit.bxor(v,gf.mul(0x04, bit.bxor(b2,b0)));
  263.     v = bit.bxor(v,gf.mul(0x04, bit.bxor(b3,b1)));
  264.    
  265.     return util.putByte( bit.bxor(bit.bxor(b3,v), gf.mul(0x02, bit.bxor(b0,b3))), 0)
  266.          + util.putByte( bit.bxor(bit.bxor(b2,w), gf.mul(0x02, t              )), 1)
  267.          + util.putByte( bit.bxor(bit.bxor(b1,v), gf.mul(0x02, bit.bxor(b0,b3))), 2)
  268.          + util.putByte( bit.bxor(bit.bxor(b0,w), gf.mul(0x02, u              )), 3);
  269. end
  270.  
  271. --
  272. -- generate key schedule for aes decryption
  273. --
  274. -- uses key schedule for aes encryption and transforms each
  275. -- key by inverse mix column.
  276. --
  277. function public.expandDecryptionKey(key)
  278.     local keySchedule = public.expandEncryptionKey(key);
  279.     if (keySchedule == nil) then
  280.         return nil;
  281.     end
  282.    
  283.     keySchedule[public.KEY_TYPE] = public.DECRYPTION_KEY;    
  284.  
  285.     for i = 4, (keySchedule[public.ROUNDS] + 1)*4 - 5 do
  286.         keySchedule[i] = private.invMixColumnOld(keySchedule[i]);
  287.     end
  288.    
  289.     return keySchedule;
  290. end
  291.  
  292. --
  293. -- xor round key to state
  294. --
  295. function private.addRoundKey(state, key, round)
  296.     for i = 0, 3 do
  297.         state[i] = bit.bxor(state[i], key[round*4+i]);
  298.     end
  299. end
  300.  
  301. --
  302. -- do encryption round (ShiftRow, SubBytes, MixColumn together)
  303. --
  304. function private.doRound(origState, dstState)
  305.     dstState[0] =  bit.bxor(bit.bxor(bit.bxor(
  306.                 private.table0[util.getByte(origState[0],3)],
  307.                 private.table1[util.getByte(origState[1],2)]),
  308.                 private.table2[util.getByte(origState[2],1)]),
  309.                 private.table3[util.getByte(origState[3],0)]);
  310.  
  311.     dstState[1] =  bit.bxor(bit.bxor(bit.bxor(
  312.                 private.table0[util.getByte(origState[1],3)],
  313.                 private.table1[util.getByte(origState[2],2)]),
  314.                 private.table2[util.getByte(origState[3],1)]),
  315.                 private.table3[util.getByte(origState[0],0)]);
  316.    
  317.     dstState[2] =  bit.bxor(bit.bxor(bit.bxor(
  318.                 private.table0[util.getByte(origState[2],3)],
  319.                 private.table1[util.getByte(origState[3],2)]),
  320.                 private.table2[util.getByte(origState[0],1)]),
  321.                 private.table3[util.getByte(origState[1],0)]);
  322.    
  323.     dstState[3] =  bit.bxor(bit.bxor(bit.bxor(
  324.                 private.table0[util.getByte(origState[3],3)],
  325.                 private.table1[util.getByte(origState[0],2)]),
  326.                 private.table2[util.getByte(origState[1],1)]),
  327.                 private.table3[util.getByte(origState[2],0)]);
  328. end
  329.  
  330. --
  331. -- do last encryption round (ShiftRow and SubBytes)
  332. --
  333. function private.doLastRound(origState, dstState)
  334.     dstState[0] = util.putByte(private.SBox[util.getByte(origState[0],3)], 3)
  335.                 + util.putByte(private.SBox[util.getByte(origState[1],2)], 2)
  336.                 + util.putByte(private.SBox[util.getByte(origState[2],1)], 1)
  337.                 + util.putByte(private.SBox[util.getByte(origState[3],0)], 0);
  338.  
  339.     dstState[1] = util.putByte(private.SBox[util.getByte(origState[1],3)], 3)
  340.                 + util.putByte(private.SBox[util.getByte(origState[2],2)], 2)
  341.                 + util.putByte(private.SBox[util.getByte(origState[3],1)], 1)
  342.                 + util.putByte(private.SBox[util.getByte(origState[0],0)], 0);
  343.  
  344.     dstState[2] = util.putByte(private.SBox[util.getByte(origState[2],3)], 3)
  345.                 + util.putByte(private.SBox[util.getByte(origState[3],2)], 2)
  346.                 + util.putByte(private.SBox[util.getByte(origState[0],1)], 1)
  347.                 + util.putByte(private.SBox[util.getByte(origState[1],0)], 0);
  348.  
  349.     dstState[3] = util.putByte(private.SBox[util.getByte(origState[3],3)], 3)
  350.                 + util.putByte(private.SBox[util.getByte(origState[0],2)], 2)
  351.                 + util.putByte(private.SBox[util.getByte(origState[1],1)], 1)
  352.                 + util.putByte(private.SBox[util.getByte(origState[2],0)], 0);
  353. end
  354.  
  355. --
  356. -- do decryption round
  357. --
  358. function private.doInvRound(origState, dstState)
  359.     dstState[0] =  bit.bxor(bit.bxor(bit.bxor(
  360.                 private.tableInv0[util.getByte(origState[0],3)],
  361.                 private.tableInv1[util.getByte(origState[3],2)]),
  362.                 private.tableInv2[util.getByte(origState[2],1)]),
  363.                 private.tableInv3[util.getByte(origState[1],0)]);
  364.  
  365.     dstState[1] =  bit.bxor(bit.bxor(bit.bxor(
  366.                 private.tableInv0[util.getByte(origState[1],3)],
  367.                 private.tableInv1[util.getByte(origState[0],2)]),
  368.                 private.tableInv2[util.getByte(origState[3],1)]),
  369.                 private.tableInv3[util.getByte(origState[2],0)]);
  370.    
  371.     dstState[2] =  bit.bxor(bit.bxor(bit.bxor(
  372.                 private.tableInv0[util.getByte(origState[2],3)],
  373.                 private.tableInv1[util.getByte(origState[1],2)]),
  374.                 private.tableInv2[util.getByte(origState[0],1)]),
  375.                 private.tableInv3[util.getByte(origState[3],0)]);
  376.    
  377.     dstState[3] =  bit.bxor(bit.bxor(bit.bxor(
  378.                 private.tableInv0[util.getByte(origState[3],3)],
  379.                 private.tableInv1[util.getByte(origState[2],2)]),
  380.                 private.tableInv2[util.getByte(origState[1],1)]),
  381.                 private.tableInv3[util.getByte(origState[0],0)]);
  382. end
  383.  
  384. --
  385. -- do last decryption round
  386. --
  387. function private.doInvLastRound(origState, dstState)
  388.     dstState[0] = util.putByte(private.iSBox[util.getByte(origState[0],3)], 3)
  389.                 + util.putByte(private.iSBox[util.getByte(origState[3],2)], 2)
  390.                 + util.putByte(private.iSBox[util.getByte(origState[2],1)], 1)
  391.                 + util.putByte(private.iSBox[util.getByte(origState[1],0)], 0);
  392.  
  393.     dstState[1] = util.putByte(private.iSBox[util.getByte(origState[1],3)], 3)
  394.                 + util.putByte(private.iSBox[util.getByte(origState[0],2)], 2)
  395.                 + util.putByte(private.iSBox[util.getByte(origState[3],1)], 1)
  396.                 + util.putByte(private.iSBox[util.getByte(origState[2],0)], 0);
  397.  
  398.     dstState[2] = util.putByte(private.iSBox[util.getByte(origState[2],3)], 3)
  399.                 + util.putByte(private.iSBox[util.getByte(origState[1],2)], 2)
  400.                 + util.putByte(private.iSBox[util.getByte(origState[0],1)], 1)
  401.                 + util.putByte(private.iSBox[util.getByte(origState[3],0)], 0);
  402.  
  403.     dstState[3] = util.putByte(private.iSBox[util.getByte(origState[3],3)], 3)
  404.                 + util.putByte(private.iSBox[util.getByte(origState[2],2)], 2)
  405.                 + util.putByte(private.iSBox[util.getByte(origState[1],1)], 1)
  406.                 + util.putByte(private.iSBox[util.getByte(origState[0],0)], 0);
  407. end
  408.  
  409. --
  410. -- encrypts 16 Bytes
  411. -- key           encryption key schedule
  412. -- input         array with input data
  413. -- inputOffset   start index for input
  414. -- output        array for encrypted data
  415. -- outputOffset  start index for output
  416. --
  417. function public.encrypt(key, input, inputOffset, output, outputOffset)
  418.     --default parameters
  419.     inputOffset = inputOffset or 1;
  420.     output = output or {};
  421.     outputOffset = outputOffset or 1;
  422.  
  423.     local state = {};
  424.     local tmpState = {};
  425.    
  426.     if (key[public.KEY_TYPE] ~= public.ENCRYPTION_KEY) then
  427.         print("No encryption key: ", key[public.KEY_TYPE]);
  428.         return;
  429.     end
  430.  
  431.     state = util.bytesToInts(input, inputOffset, 4);
  432.     private.addRoundKey(state, key, 0);
  433.  
  434.     local round = 1;
  435.     while (round < key[public.ROUNDS] - 1) do
  436.         -- do a double round to save temporary assignments
  437.         private.doRound(state, tmpState);
  438.         private.addRoundKey(tmpState, key, round);
  439.         round = round + 1;
  440.  
  441.         private.doRound(tmpState, state);
  442.         private.addRoundKey(state, key, round);
  443.         round = round + 1;
  444.     end
  445.    
  446.     private.doRound(state, tmpState);
  447.     private.addRoundKey(tmpState, key, round);
  448.     round = round +1;
  449.  
  450.     private.doLastRound(tmpState, state);
  451.     private.addRoundKey(state, key, round);
  452.    
  453.     return util.intsToBytes(state, output, outputOffset);
  454. end
  455.  
  456. --
  457. -- decrypt 16 bytes
  458. -- key           decryption key schedule
  459. -- input         array with input data
  460. -- inputOffset   start index for input
  461. -- output        array for decrypted data
  462. -- outputOffset  start index for output
  463. ---
  464. function public.decrypt(key, input, inputOffset, output, outputOffset)
  465.     -- default arguments
  466.     inputOffset = inputOffset or 1;
  467.     output = output or {};
  468.     outputOffset = outputOffset or 1;
  469.  
  470.     local state = {};
  471.     local tmpState = {};
  472.  
  473.     if (key[public.KEY_TYPE] ~= public.DECRYPTION_KEY) then
  474.         print("No decryption key: ", key[public.KEY_TYPE]);
  475.         return;
  476.     end
  477.  
  478.     state = util.bytesToInts(input, inputOffset, 4);
  479.     private.addRoundKey(state, key, key[public.ROUNDS]);
  480.  
  481.     local round = key[public.ROUNDS] - 1;
  482.     while (round > 2) do
  483.         -- do a double round to save temporary assignments
  484.         private.doInvRound(state, tmpState);
  485.         private.addRoundKey(tmpState, key, round);
  486.         round = round - 1;
  487.  
  488.         private.doInvRound(tmpState, state);
  489.         private.addRoundKey(state, key, round);
  490.         round = round - 1;
  491.     end
  492.    
  493.     private.doInvRound(state, tmpState);
  494.     private.addRoundKey(tmpState, key, round);
  495.     round = round - 1;
  496.  
  497.     private.doInvLastRound(tmpState, state);
  498.     private.addRoundKey(state, key, round);
  499.    
  500.     return util.intsToBytes(state, output, outputOffset);
  501. end
  502.  
  503. -- calculate all tables when loading this file
  504. private.calcSBox();
  505. private.calcRoundTables();
  506. private.calcInvRoundTables();
  507.  
  508. return public;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement