⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ffdecsa.c

📁 VDR softcam plugin 0.9.1
💻 C
📖 第 1 页 / 共 2 页
字号:
      XOREQ_BEST_BY(&r[roff+GROUP_PARALLELISM*4+g],&r[roff+GROUP_PARALLELISM*0+g]);      XOREQ_BEST_BY(&r[roff+GROUP_PARALLELISM*3+g],&r[roff+GROUP_PARALLELISM*0+g]);      XOREQ_BEST_BY(&r[roff+GROUP_PARALLELISM*2+g],&r[roff+GROUP_PARALLELISM*0+g]);    }#endif  }#define FASTTRASP2#ifndef FASTTRASP2  for(g=0;g<count;g++){    // Copy results    int j;    for(j=0;j<8;j++){      bd[8*g+j]=r[roff+GROUP_PARALLELISM*j+g];    }  }#else  trasp_8_N((unsigned char *)&r[roff],(unsigned char *)bd,count);#endif}//-----------------------------------EXTERNAL INTERFACE//-----get internal parallelismint get_internal_parallelism(void){  return GROUP_PARALLELISM;}//-----get suggested cluster sizeint get_suggested_cluster_size(void){  int r;  r=GROUP_PARALLELISM+GROUP_PARALLELISM/10;  if(r<GROUP_PARALLELISM+5) r=GROUP_PARALLELISM+5;  return r;}//-----key structurevoid *get_key_struct(void){  struct csa_keys_t *keys=(struct csa_keys_t *)MALLOC(sizeof(struct csa_keys_t));  if(keys) {    static const unsigned char pk[8] = { 0,0,0,0,0,0,0,0 };    set_control_words(keys,pk,pk);    }  return keys;}void free_key_struct(void *keys){  return FREE(keys);}//-----set control wordsstatic void schedule_key(struct csa_key_t *key, const unsigned char *pk){  // could be made faster, but is not run often  int bi,by;  int i,j;// key  memcpy(key->ck,pk,8);// precalculations for stream  key_schedule_stream(key->ck,key->iA,key->iB);  for(by=0;by<8;by++){    for(bi=0;bi<8;bi++){      key->ck_g[by][bi]=(key->ck[by]&(1<<bi))?FF1():FF0();    }  }  for(by=0;by<8;by++){    for(bi=0;bi<4;bi++){      key->iA_g[by][bi]=(key->iA[by]&(1<<bi))?FF1():FF0();      key->iB_g[by][bi]=(key->iB[by]&(1<<bi))?FF1():FF0();    }  }// precalculations for block  key_schedule_block(key->ck,key->kk);  for(i=0;i<56;i++){    for(j=0;j<BYTES_PER_BATCH;j++){      *(((unsigned char *)&key->kkmulti[i])+j)=key->kk[i];    }  }}void set_control_words(void *keys, const unsigned char *ev, const unsigned char *od){  schedule_key(&((struct csa_keys_t *)keys)->even,ev);  schedule_key(&((struct csa_keys_t *)keys)->odd,od);}void set_even_control_word(void *keys, const unsigned char *pk){  schedule_key(&((struct csa_keys_t *)keys)->even,pk);}void set_odd_control_word(void *keys, const unsigned char *pk){  schedule_key(&((struct csa_keys_t *)keys)->odd,pk);}//-----get control wordsvoid get_control_words(void *keys, unsigned char *even, unsigned char *odd){  memcpy(even,&((struct csa_keys_t *)keys)->even.ck,8);  memcpy(odd,&((struct csa_keys_t *)keys)->odd.ck,8);}//----- decryptint decrypt_packets(void *keys, unsigned char **cluster){  // statistics, currently unused  int stat_no_scramble=0;  int stat_reserved=0;  int stat_decrypted[2]={0,0};  int stat_decrypted_mini=0;  unsigned char **clst;  unsigned char **clst2;  int grouped;  int group_ev_od;  int advanced;  int can_advance;  unsigned char *g_pkt[GROUP_PARALLELISM];  int g_len[GROUP_PARALLELISM];  int g_offset[GROUP_PARALLELISM];  int g_n[GROUP_PARALLELISM];  int g_residue[GROUP_PARALLELISM];  unsigned char *pkt;  int xc0,ev_od,len,offset,n,residue;  struct csa_key_t* k;  int i,j,iter,g;  int t23,tsmall;  int alive[24];//icc craziness  int pad1=0; //////////align! FIXME  unsigned char *encp[GROUP_PARALLELISM];  unsigned char stream_in[GROUP_PARALLELISM*8];  unsigned char stream_out[GROUP_PARALLELISM*8];  MEMALIGN unsigned char ib[GROUP_PARALLELISM*8];  MEMALIGN unsigned char block_out[GROUP_PARALLELISM*8];  struct stream_regs regs;//icc craziness  i=(int)&pad1;//////////align!!! FIXME  // build a list of packets to be processed  clst=cluster;  grouped=0;  advanced=0;  can_advance=1;  group_ev_od=-1; // silence incorrect compiler warning  pkt=*clst;  do{ // find a new packet    if(grouped==GROUP_PARALLELISM){      // full      break;    }    if(pkt==NULL){      // no more ranges      break;    }    if(pkt>=*(clst+1)){      // out of this range, try next      clst++;clst++;      pkt=*clst;      continue;    }    do{ // handle this packet      xc0=pkt[3]&0xc0;      DBG(fprintf(stderr,"   exam pkt=%p, xc0=%02x, can_adv=%i\n",pkt,xc0,can_advance));      if(xc0==0x00){        DBG(fprintf(stderr,"skip clear pkt %p (can_advance is %i)\n",pkt,can_advance));        advanced+=can_advance;        stat_no_scramble++;        break;      }      if(xc0==0x40){        DBG(fprintf(stderr,"skip reserved pkt %p (can_advance is %i)\n",pkt,can_advance));        advanced+=can_advance;        stat_reserved++;        break;      }      if(xc0==0x80||xc0==0xc0){ // encrypted        ev_od=(xc0&0x40)>>6; // 0 even, 1 odd        if(grouped==0) group_ev_od=ev_od; // this group will be all even (or odd)        if(group_ev_od==ev_od){ // could be added to group          pkt[3]&=0x3f;  // consider it decrypted now          if(pkt[3]&0x20){ // incomplete packet            offset=4+pkt[4]+1;            len=188-offset;            n=len>>3;            residue=len-(n<<3);            if(n==0){ // decrypted==encrypted!              DBG(fprintf(stderr,"DECRYPTED MINI! (can_advance is %i)\n",can_advance));              advanced+=can_advance;              stat_decrypted_mini++;              break; // this doesn't need more processing            }          }else{            len=184;            offset=4;            n=23;            residue=0;          }          g_pkt[grouped]=pkt;          g_len[grouped]=len;          g_offset[grouped]=offset;          g_n[grouped]=n;          g_residue[grouped]=residue;          DBG(fprintf(stderr,"%2i: eo=%i pkt=%p len=%03i n=%2i residue=%i\n",grouped,ev_od,pkt,len,n,residue));          grouped++;          advanced+=can_advance;          stat_decrypted[ev_od]++;        }        else{          can_advance=0;          DBG(fprintf(stderr,"skip pkt %p and can_advance set to 0\n",pkt));          break; // skip and go on        }      }    } while(0);    if(can_advance){      // move range start forward      *clst+=188;    }    // next packet, if there is one    pkt+=188;  } while(1);  DBG(fprintf(stderr,"-- result: grouped %i pkts, advanced %i pkts\n",grouped,advanced));  // delete empty ranges and compact list  clst2=cluster;  for(clst=cluster;*clst!=NULL;clst+=2){    // if not empty    if(*clst<*(clst+1)){      // it will remain       *clst2=*clst;      *(clst2+1)=*(clst+1);      clst2+=2;    }  }  *clst2=NULL;  if(grouped==0){    // no processing needed    return advanced;  }  //  sort them, longest payload first  //  we expect many n=23 packets and a few n<23  DBG(fprintf(stderr,"PRESORTING\n"));  for(i=0;i<grouped;i++){    DBG(fprintf(stderr,"%2i of %2i: pkt=%p len=%03i n=%2i residue=%i\n",i,grouped,g_pkt[i],g_len[i],g_n[i],g_residue[i]));    }  // grouped is always <= GROUP_PARALLELISM#define g_swap(a,b) \    pkt=g_pkt[a]; \    g_pkt[a]=g_pkt[b]; \    g_pkt[b]=pkt; \\    len=g_len[a]; \    g_len[a]=g_len[b]; \    g_len[b]=len; \\    offset=g_offset[a]; \    g_offset[a]=g_offset[b]; \    g_offset[b]=offset; \\    n=g_n[a]; \    g_n[a]=g_n[b]; \    g_n[b]=n; \\    residue=g_residue[a]; \    g_residue[a]=g_residue[b]; \    g_residue[b]=residue;  // step 1: move n=23 packets before small packets  t23=0;  tsmall=grouped-1;  for(;;){    for(;t23<grouped;t23++){      if(g_n[t23]!=23) break;    }DBG(fprintf(stderr,"t23 after for =%i\n",t23));        for(;tsmall>=0;tsmall--){      if(g_n[tsmall]==23) break;    }DBG(fprintf(stderr,"tsmall after for =%i\n",tsmall));        if(tsmall-t23<1) break;    DBG(fprintf(stderr,"swap t23=%i,tsmall=%i\n",t23,tsmall));    g_swap(t23,tsmall);    t23++;    tsmall--;DBG(fprintf(stderr,"new t23=%i,tsmall=%i\n\n",t23,tsmall));  }  DBG(fprintf(stderr,"packets with n=23, t23=%i   grouped=%i\n",t23,grouped));  DBG(fprintf(stderr,"MIDSORTING\n"));  for(i=0;i<grouped;i++){    DBG(fprintf(stderr,"%2i of %2i: pkt=%p len=%03i n=%2i residue=%i\n",i,grouped,g_pkt[i],g_len[i],g_n[i],g_residue[i]));    }  // step 2: sort small packets in decreasing order of n (bubble sort is enough)  for(i=t23;i<grouped;i++){    for(j=i+1;j<grouped;j++){      if(g_n[j]>g_n[i]){        g_swap(i,j);      }    }  }  DBG(fprintf(stderr,"POSTSORTING\n"));  for(i=0;i<grouped;i++){    DBG(fprintf(stderr,"%2i of %2i: pkt=%p len=%03i n=%2i residue=%i\n",i,grouped,g_pkt[i],g_len[i],g_n[i],g_residue[i]));    }  // we need to know how many packets need 23 iterations, how many 22...  for(i=0;i<=23;i++){    alive[i]=0;  }  // count  alive[23-1]=t23;  for(i=t23;i<grouped;i++){    alive[g_n[i]-1]++;  }  // integrate  for(i=22;i>=0;i--){    alive[i]+=alive[i+1];  }  DBG(fprintf(stderr,"ALIVE\n"));  for(i=0;i<=23;i++){    DBG(fprintf(stderr,"alive%2i=%i\n",i,alive[i]));    }  // choose key  if(group_ev_od==0){    k=&((struct csa_keys_t *)keys)->even;  }  else{    k=&((struct csa_keys_t *)keys)->odd;  }  //INIT//#define INITIALIZE_UNUSED_INPUT#ifdef INITIALIZE_UNUSED_INPUT// unnecessary zeroing.// without this, we operate on uninitialized memory// when grouped<GROUP_PARALLELISM, but it's not a problem,// as final results will be discarded.// random data makes debugging sessions difficult.  for(j=0;j<GROUP_PARALLELISM*8;j++) stream_in[j]=0;DBG(fprintf(stderr,"--- WARNING: you could gain speed by not initializing unused memory ---\n"));#elseDBG(fprintf(stderr,"--- WARNING: DEBUGGING IS MORE DIFFICULT WHEN PROCESSING RANDOM DATA CHANGING AT EVERY RUN! ---\n"));#endif  for(g=0;g<grouped;g++){    encp[g]=g_pkt[g];    DBG(fprintf(stderr,"header[%i]=%p (%02x)\n",g,encp[g],*(encp[g])));    encp[g]+=g_offset[g]; // skip header    FFTABLEIN(stream_in,g,encp[g]);  }//dump_mem("stream_in",stream_in,GROUP_PARALLELISM*8,BYPG);  // ITER 0DBG(fprintf(stderr,">>>>>ITER 0\n"));  iter=0;  stream_cypher_group_init(&regs,k->iA_g,k->iB_g,stream_in);  // fill first ib  for(g=0;g<alive[iter];g++){    COPY_8_BY(ib+8*g,encp[g]);  }DBG(dump_mem("IB ",ib,8*alive[iter],8));  // ITER 1..N-1  for (iter=1;iter<23&&alive[iter-1]>0;iter++){DBG(fprintf(stderr,">>>>>ITER %i\n",iter));    // alive and just dead packets: calc block    block_decypher_group(k->kkmulti,ib,block_out,alive[iter-1]);DBG(dump_mem("BLO_ib ",block_out,8*alive[iter-1],8));    // all packets (dead too): calc stream    stream_cypher_group_normal(&regs,stream_out);//dump_mem("stream_out",stream_out,GROUP_PARALLELISM*8,BYPG);    // alive packets: calc ib    for(g=0;g<alive[iter];g++){      FFTABLEOUT(ib+8*g,stream_out,g);DBG(dump_mem("stream_out_ib ",ib+8*g,8,8));// XOREQ8BY gcc bug? 2x4 ok, 8 ko    UPDATE: result ok but speed 1-2% slower (!!!???)#if 1      XOREQ_4_BY(ib+8*g,encp[g]+8);      XOREQ_4_BY(ib+8*g+4,encp[g]+8+4);#else      XOREQ_8_BY(ib+8*g,encp[g]+8);#endifDBG(dump_mem("after_stream_xor_ib ",ib+8*g,8,8));    }    // alive packets: decrypt data    for(g=0;g<alive[iter];g++){DBG(dump_mem("before_ib_decrypt_data ",encp[g],8,8));      XOR_8_BY(encp[g],ib+8*g,block_out+8*g);DBG(dump_mem("after_ib_decrypt_data ",encp[g],8,8));    }    // just dead packets: write decrypted data    for(g=alive[iter];g<alive[iter-1];g++){DBG(dump_mem("jd_before_ib_decrypt_data ",encp[g],8,8));      COPY_8_BY(encp[g],block_out+8*g);DBG(dump_mem("jd_after_ib_decrypt_data ",encp[g],8,8));    }    // just dead packets: decrypt residue    for(g=alive[iter];g<alive[iter-1];g++){DBG(dump_mem("jd_before_decrypt_residue ",encp[g]+8,g_residue[g],g_residue[g]));      FFTABLEOUTXORNBY(g_residue[g],encp[g]+8,stream_out,g);DBG(dump_mem("jd_after_decrypt_residue ",encp[g]+8,g_residue[g],g_residue[g]));    }    // alive packets: pointers++    for(g=0;g<alive[iter];g++) encp[g]+=8;  };  // ITER NDBG(fprintf(stderr,">>>>>ITER 23\n"));  iter=23;  // calc block  block_decypher_group(k->kkmulti,ib,block_out,alive[iter-1]);DBG(dump_mem("23BLO_ib ",block_out,8*alive[iter-1],8));  // just dead packets: write decrypted data  for(g=alive[iter];g<alive[iter-1];g++){DBG(dump_mem("23jd_before_ib_decrypt_data ",encp[g],8,8));    COPY_8_BY(encp[g],block_out+8*g);DBG(dump_mem("23jd_after_ib_decrypt_data ",encp[g],8,8));  }  // no residue possible  // so do nothing  DBG(fprintf(stderr,"returning advanced=%i\n",advanced));  M_EMPTY(); // restore CPU multimedia state  return advanced;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -