Advertisement
trmr

CSAW CTF 2014 feal writeup (1/2)

Feb 14th, 2016
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.84 KB | None | 0 0
  1.  
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #define NUM_CHECK 10
  6.  
  7. unsigned int pa_list[NUM_CHECK][2];
  8. unsigned int pb_list[NUM_CHECK][2];
  9. unsigned int ca_list[NUM_CHECK][2];
  10. unsigned int cb_list[NUM_CHECK][2];
  11. unsigned int c_list[NUM_CHECK][2];
  12. unsigned int diff_cl_list[NUM_CHECK];
  13. unsigned int clcr_a_list[NUM_CHECK];
  14. unsigned int clcr_b_list[NUM_CHECK];
  15. unsigned int cand_c[2];
  16. unsigned int subkey5;
  17. unsigned int subkey4;
  18. unsigned int subkey3;
  19. unsigned int subkey2;
  20. unsigned int subkey1;
  21. unsigned int subkey0;
  22.  
  23. unsigned int byte_swap(unsigned int a){
  24.   return (((a>>0)&0xff)<<24) | (((a>>8)&0xff)<<16) | (((a>>16)&0xff)<<8) | (((a>>24)&0xff)<<0);
  25. }
  26.  
  27. unsigned char gBox(unsigned char a, unsigned char b, unsigned char mode){
  28.   unsigned char x;
  29.   x = (a + b + mode) & 0xff;
  30.   return ((x<<3) | (x>>5)) & 0xff;
  31. }
  32.  
  33. union FEAL {
  34.   unsigned int  w;
  35.   unsigned char b[4];
  36. };
  37.  
  38. unsigned int fBox(unsigned int _src){
  39.    unsigned char t0, y1, y0, y2, y3;
  40.    union FEAL src, dest;
  41.    src.w = _src;
  42.  
  43.    t0 = src.b[2] ^ src.b[3];
  44.    y1 = gBox(src.b[0] ^ src.b[1], t0, 1);
  45.    y0 = gBox(src.b[0], y1, 0);
  46.    y2 = gBox(t0, y1, 0);
  47.    y3 = gBox(src.b[3], y2, 1);
  48.    dest.b[0] = y3;
  49.    dest.b[1] = y2;
  50.    dest.b[2] = y1;
  51.    dest.b[3] = y0;
  52.    return dest.w;
  53. }
  54.  
  55. void encrypt(unsigned int p1, unsigned int p2){
  56.   unsigned int left = p1 ^ subkey4;
  57.   unsigned int right = p2 ^ subkey5;
  58.   unsigned int R2L = left ^ right;
  59.   unsigned int R2R = left ^ fBox(R2L ^ subkey0);
  60.   unsigned int R3L = R2R;
  61.   unsigned int R3R = R2L ^ fBox(R2R ^ subkey1);
  62.   unsigned int R4L = R3R;
  63.   unsigned int R4R = R3L ^ fBox(R3R ^ subkey2);
  64.   unsigned int R5L = R4L ^ fBox(R4R ^ subkey3);
  65.   unsigned int R5R = R5L ^ R4R;
  66.   cand_c[0] = R5L;
  67.   cand_c[1] = R5R;
  68. }
  69.  
  70. void brute1(){
  71.   int x;
  72.   unsigned long subkey;
  73.  
  74.   for (subkey=0; subkey<0x100000000; subkey++){
  75.     if (subkey % 0x1000000 == 0) fprintf(stderr, "calculating... %#010lx\n", subkey); // debug
  76.  
  77.     for (x=0; x<NUM_CHECK; x++){
  78.        if (fBox(clcr_a_list[x] ^ subkey) ^ fBox(clcr_b_list[x] ^ subkey) ^ 0x04000000 ^ diff_cl_list[x]){
  79.          break;
  80.        }
  81.     }
  82.     if (x==NUM_CHECK){
  83.       printf("%#010lx", subkey);
  84.       exit(0);
  85.     }
  86.   }
  87. }
  88.  
  89. void brute2(){
  90.   int x;
  91.   unsigned long subkey;
  92.  
  93.   for (subkey=0; subkey<0x100000000; subkey++){
  94.     if (subkey % 0x1000000 == 0) fprintf(stderr, "calculating... %#010lx\n", subkey); // debug
  95.  
  96.     subkey0 = subkey;
  97.     for (x=0; x<NUM_CHECK-1; x++){
  98.        subkey4 = ca_list[x][0] ^ fBox(ca_list[x][1] ^ subkey) ^ pa_list[x][0];
  99.        subkey5 = ca_list[x][1] ^ subkey4 ^ pa_list[x][0] ^ pa_list[x][1];
  100.  
  101.        encrypt(pa_list[x+1][0], pa_list[x+1][1]); // cand_c <- pa_list[x+1] with subkeys
  102.        if (c_list[x+1][0] != cand_c[0] || c_list[x+1][1] != cand_c[1]){
  103.          break;
  104.        }
  105.     }
  106.     if (x==NUM_CHECK-1){
  107.       printf("[%#010x, %#010x, %#010x, %#010x, %#010x, %#010x]", subkey0, subkey1, subkey2, subkey3, subkey4, subkey5);
  108.       exit(0);
  109.     }
  110.   }
  111. }
  112.  
  113. void parse(char **argv){
  114.   int i;
  115.   unsigned long t;
  116.   for (i=0; i<NUM_CHECK; i++){
  117.     t = strtoul(argv[i*4], 0, 16);
  118.     pa_list[i][0] = byte_swap((t>>32)&0xffffffff);
  119.     pa_list[i][1] = byte_swap(t&0xffffffff);
  120.     t = strtoul(argv[i*4+1], 0, 16);
  121.     pb_list[i][0] = byte_swap((t>>32)&0xffffffff);
  122.     pb_list[i][1] = byte_swap(t&0xffffffff);
  123.     t = strtoul(argv[i*4+2], 0, 16);
  124.     ca_list[i][0] = byte_swap((t>>32)&0xffffffff);
  125.     ca_list[i][1] = byte_swap(t&0xffffffff);
  126.     t = strtoul(argv[i*4+3], 0, 16);
  127.     cb_list[i][0] = byte_swap((t>>32)&0xffffffff);
  128.     cb_list[i][1] = byte_swap(t&0xffffffff);
  129.   }
  130. }
  131.  
  132. void recover_4th_round(int i, unsigned int subkey){
  133.   unsigned int cl, cr;
  134.   cl = ca_list[i][0] ^ ca_list[i][1];
  135.   cr = ca_list[i][0] ^ fBox(cl ^ subkey);
  136.   ca_list[i][0] = cl;
  137.   ca_list[i][1] = cr;
  138.  
  139.   cl = cb_list[i][0] ^ cb_list[i][1];
  140.   cr = cb_list[i][0] ^ fBox(cl ^ subkey);
  141.   cb_list[i][0] = cl;
  142.   cb_list[i][1] = cr;
  143. }
  144.  
  145. void recover_round(int i, unsigned int subkey){
  146.   unsigned int cl, cr;
  147.   cl = ca_list[i][1];
  148.   cr = ca_list[i][0] ^ fBox(cl ^ subkey);
  149.   ca_list[i][0] = cl;
  150.   ca_list[i][1] = cr;
  151.  
  152.   cl = cb_list[i][1];
  153.   cr = cb_list[i][0] ^ fBox(cl ^ subkey);
  154.   cb_list[i][0] = cl;
  155.   cb_list[i][1] = cr;
  156. }
  157.  
  158. int main(int argc, char *argv[]){
  159.   int mode = atoi(argv[1]);
  160.   int i;
  161.  
  162.   switch (mode){
  163.     case 3:
  164.       parse(&argv[2]);
  165.       for (i=0; i<NUM_CHECK; i++){
  166.         diff_cl_list[i] = ca_list[i][0] ^ cb_list[i][0];
  167.         clcr_a_list[i] = ca_list[i][0] ^ ca_list[i][1];
  168.         clcr_b_list[i] = cb_list[i][0] ^ cb_list[i][1];
  169.       }
  170.       brute1();
  171.  
  172.     case 2:
  173.       subkey3 = strtoul(argv[2], 0, 16);
  174.       parse(&argv[3]);
  175.  
  176.       for (i=0; i<NUM_CHECK; i++){
  177.         recover_4th_round(i, subkey3);
  178.         diff_cl_list[i] = ca_list[i][0] ^ cb_list[i][0];
  179.         clcr_a_list[i] = ca_list[i][1];
  180.         clcr_b_list[i] = cb_list[i][1];
  181.       }
  182.       brute1();
  183.  
  184.     case 1:
  185.       subkey3 = strtoul(argv[2], 0, 16);
  186.       subkey2 = strtoul(argv[3], 0, 16);
  187.       parse(&argv[4]);
  188.  
  189.       for (i=0; i<NUM_CHECK; i++){
  190.         recover_4th_round(i, subkey3);
  191.         recover_round(i, subkey2);
  192.         diff_cl_list[i] = ca_list[i][0] ^ cb_list[i][0];
  193.         clcr_a_list[i] = ca_list[i][1];
  194.         clcr_b_list[i] = cb_list[i][1];
  195.       }
  196.       brute1();
  197.  
  198.     case 0:
  199.       subkey3 = strtoul(argv[2], 0, 16);
  200.       subkey2 = strtoul(argv[3], 0, 16);
  201.       subkey1 = strtoul(argv[4], 0, 16);
  202.       parse(&argv[5]);
  203.  
  204.       for (i=0; i<NUM_CHECK; i++){
  205.         c_list[i][0] = ca_list[i][0];
  206.         c_list[i][1] = ca_list[i][1];
  207.         recover_4th_round(i, subkey3);
  208.         recover_round(i, subkey2);
  209.         recover_round(i, subkey1);
  210.       }
  211.       brute2();
  212.  
  213.     default:
  214.       exit(0);
  215.   }
  216. }
  217. writeup_feal.c
  218. Ryoichi TERAMURA
  219. (ryo1.teramura@gmail.com)Displaying writeup_feal.c.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement