SASC-NG
DVBSoftCAM

FFdecsa.c

Go to the documentation of this file.
00001 /* FFdecsa -- fast decsa algorithm
00002  *
00003  * Copyright (C) 2003-2004  fatih89r
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018  */
00019 
00020 
00021 #include <sys/types.h>
00022 #include <string.h>
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 
00026 #include "FFdecsa.h"
00027 
00028 #ifndef NULL
00029 #define NULL 0
00030 #endif
00031 
00032 //#define DEBUG
00033 #ifdef DEBUG
00034 #define DBG(a) a
00035 #else
00036 #define DBG(a)
00037 #endif
00038 
00040 // possible choices
00041 #define PARALLEL_32_4CHAR     320
00042 #define PARALLEL_32_4CHARA    321
00043 #define PARALLEL_32_INT       322
00044 #define PARALLEL_64_8CHAR     640
00045 #define PARALLEL_64_8CHARA    641
00046 #define PARALLEL_64_2INT      642
00047 #define PARALLEL_64_LONG      643
00048 #define PARALLEL_64_MMX       644
00049 #define PARALLEL_128_16CHAR  1280
00050 #define PARALLEL_128_16CHARA 1281
00051 #define PARALLEL_128_4INT    1282
00052 #define PARALLEL_128_2LONG   1283
00053 #define PARALLEL_128_2MMX    1284
00054 #define PARALLEL_128_SSE     1285
00055 #define PARALLEL_128_SSE2    1286
00056 
00058 #ifndef PARALLEL_MODE
00059 #define PARALLEL_MODE PARALLEL_32_INT
00060 #endif
00061 
00062 
00063 #include "parallel_generic.h"
00065 #if PARALLEL_MODE==PARALLEL_32_4CHAR
00066 #include "parallel_032_4char.h"
00067 #elif PARALLEL_MODE==PARALLEL_32_4CHARA
00068 #include "parallel_032_4charA.h"
00069 #elif PARALLEL_MODE==PARALLEL_32_INT
00070 #include "parallel_032_int.h"
00071 #elif PARALLEL_MODE==PARALLEL_64_8CHAR
00072 #include "parallel_064_8char.h"
00073 #elif PARALLEL_MODE==PARALLEL_64_8CHARA
00074 #include "parallel_064_8charA.h"
00075 #elif PARALLEL_MODE==PARALLEL_64_2INT
00076 #include "parallel_064_2int.h"
00077 #elif PARALLEL_MODE==PARALLEL_64_LONG
00078 #include "parallel_064_long.h"
00079 #elif PARALLEL_MODE==PARALLEL_64_MMX
00080 #include "parallel_064_mmx.h"
00081 #elif PARALLEL_MODE==PARALLEL_128_16CHAR
00082 #include "parallel_128_16char.h"
00083 #elif PARALLEL_MODE==PARALLEL_128_16CHARA
00084 #include "parallel_128_16charA.h"
00085 #elif PARALLEL_MODE==PARALLEL_128_4INT
00086 #include "parallel_128_4int.h"
00087 #elif PARALLEL_MODE==PARALLEL_128_2LONG
00088 #include "parallel_128_2long.h"
00089 #elif PARALLEL_MODE==PARALLEL_128_2MMX
00090 #include "parallel_128_2mmx.h"
00091 #elif PARALLEL_MODE==PARALLEL_128_SSE
00092 #include "parallel_128_sse.h"
00093 #elif PARALLEL_MODE==PARALLEL_128_SSE2
00094 #include "parallel_128_sse2.h"
00095 #else
00096 #error "unknown/undefined parallel mode"
00097 #endif
00098 
00099 // stuff depending on conditionals
00100 
00101 #define BYTES_PER_GROUP (GROUP_PARALLELISM/8)
00102 #define BYPG BYTES_PER_GROUP
00103 #define BITS_PER_GROUP GROUP_PARALLELISM
00104 #define BIPG BITS_PER_GROUP
00105 
00106 // platform specific
00107 
00108 #ifdef __arm__
00109 #if !defined(MEMALIGN_VAL) || MEMALIGN_VAL<4
00110 #undef MEMALIGN_VAL
00111 #define MEMALIGN_VAL 4
00112 #endif
00113 #define COPY_UNALIGNED_PKT
00114 #endif
00115 
00116 //
00117 
00118 #ifndef MALLOC
00119 #define MALLOC(X) malloc(X)
00120 #endif
00121 #ifndef FREE
00122 #define FREE(X) free(X)
00123 #endif
00124 #ifdef MEMALIGN_VAL
00125 #define MEMALIGN __attribute__((aligned(MEMALIGN_VAL)))
00126 #else
00127 #define MEMALIGN
00128 #endif
00129 
00131 
00132 #ifdef DEBUG
00133 static void dump_mem(const char *string, const unsigned char *p, int len, int linelen){
00134   int i;
00135   for(i=0;i<len;i++){
00136     if(i%linelen==0&&i) fprintf(stderr,"\n");
00137     if(i%linelen==0) fprintf(stderr,"%s %08x:",string,i);
00138     else{
00139       if(i%8==0) fprintf(stderr," ");
00140       if(i%4==0) fprintf(stderr," ");
00141     }
00142     fprintf(stderr," %02x",p[i]);
00143   }
00144   if(i%linelen==0) fprintf(stderr,"\n");
00145 }
00146 #endif
00147 
00149 
00150 struct csa_key_t{
00151         unsigned char ck[8];
00152 // used by stream
00153         int iA[8];  // iA[0] is for A1, iA[7] is for A8
00154         int iB[8];  // iB[0] is for B1, iB[7] is for B8
00155 // used by stream (group)
00156         MEMALIGN group ck_g[8][8]; // [byte][bit:0=LSB,7=MSB]
00157         MEMALIGN group iA_g[8][4]; // [0 for A1][0 for LSB]
00158         MEMALIGN group iB_g[8][4]; // [0 for B1][0 for LSB]
00159 // used by block
00160         unsigned char kk[56];
00161 // used by block (group)
00162         MEMALIGN batch kkmulti[56]; // many times the same byte in every batch
00163 };
00164 
00165 struct csa_keys_t{
00166   struct csa_key_t even;
00167   struct csa_key_t odd;
00168 };
00169 
00170 //-----stream cypher
00171 
00172 //-----key schedule for stream decypher
00173 static void key_schedule_stream(
00174   unsigned char *ck,    // [In]  ck[0]-ck[7]   8 bytes   | Key.
00175   int *iA,              // [Out] iA[0]-iA[7]   8 nibbles | Key schedule.
00176   int *iB)              // [Out] iB[0]-iB[7]   8 nibbles | Key schedule.
00177 {
00178     iA[0]=(ck[0]>>4)&0xf;
00179     iA[1]=(ck[0]   )&0xf;
00180     iA[2]=(ck[1]>>4)&0xf;
00181     iA[3]=(ck[1]   )&0xf;
00182     iA[4]=(ck[2]>>4)&0xf;
00183     iA[5]=(ck[2]   )&0xf;
00184     iA[6]=(ck[3]>>4)&0xf;
00185     iA[7]=(ck[3]   )&0xf;
00186     iB[0]=(ck[4]>>4)&0xf;
00187     iB[1]=(ck[4]   )&0xf;
00188     iB[2]=(ck[5]>>4)&0xf;
00189     iB[3]=(ck[5]   )&0xf;
00190     iB[4]=(ck[6]>>4)&0xf;
00191     iB[5]=(ck[6]   )&0xf;
00192     iB[6]=(ck[7]>>4)&0xf;
00193     iB[7]=(ck[7]   )&0xf;
00194 }
00195 
00196 //----- stream main function
00197 
00198 #define STREAM_INIT
00199 #include "stream.c"
00200 #undef STREAM_INIT
00201 
00202 #define STREAM_NORMAL
00203 #include "stream.c"
00204 #undef STREAM_NORMAL
00205 
00206 
00207 //-----block decypher
00208 
00209 //-----key schedule for block decypher
00210 
00211 static void key_schedule_block(
00212   unsigned char *ck,    // [In]  ck[0]-ck[7]   8 bytes | Key.
00213   unsigned char *kk)    // [Out] kk[0]-kk[55] 56 bytes | Key schedule.
00214 {
00215   static const unsigned char key_perm[0x40] = {
00216     0x12,0x24,0x09,0x07,0x2A,0x31,0x1D,0x15, 0x1C,0x36,0x3E,0x32,0x13,0x21,0x3B,0x40,
00217     0x18,0x14,0x25,0x27,0x02,0x35,0x1B,0x01, 0x22,0x04,0x0D,0x0E,0x39,0x28,0x1A,0x29,
00218     0x33,0x23,0x34,0x0C,0x16,0x30,0x1E,0x3A, 0x2D,0x1F,0x08,0x19,0x17,0x2F,0x3D,0x11,
00219     0x3C,0x05,0x38,0x2B,0x0B,0x06,0x0A,0x2C, 0x20,0x3F,0x2E,0x0F,0x03,0x26,0x10,0x37,
00220   };
00221 
00222   int i,j,k;
00223   int bit[64];
00224   int newbit[64];
00225   int kb[7][8];
00226 
00227   // 56 steps
00228   // 56 key bytes kk(55)..kk(0) by key schedule from ck
00229 
00230   // kb(6,0) .. kb(6,7) = ck(0) .. ck(7)
00231   kb[6][0] = ck[0];
00232   kb[6][1] = ck[1];
00233   kb[6][2] = ck[2];
00234   kb[6][3] = ck[3];
00235   kb[6][4] = ck[4];
00236   kb[6][5] = ck[5];
00237   kb[6][6] = ck[6];
00238   kb[6][7] = ck[7];
00239 
00240   // calculate kb[5] .. kb[0]
00241   for(i=5; i>=0; i--){
00242     // 64 bit perm on kb
00243     for(j=0; j<8; j++){
00244       for(k=0; k<8; k++){
00245         bit[j*8+k] = (kb[i+1][j] >> (7-k)) & 1;
00246         newbit[key_perm[j*8+k]-1] = bit[j*8+k];
00247       }
00248     }
00249     for(j=0; j<8; j++){
00250       kb[i][j] = 0;
00251       for(k=0; k<8; k++){
00252         kb[i][j] |= newbit[j*8+k] << (7-k);
00253       }
00254     }
00255   }
00256 
00257   // xor to give kk
00258   for(i=0; i<7; i++){
00259     for(j=0; j<8; j++){
00260       kk[i*8+j] = kb[i][j] ^ i;
00261     }
00262   }
00263 
00264 }
00265 
00266 //-----block utils
00267 
00268 static inline __attribute__((always_inline)) void trasp_N_8 (unsigned char *in,unsigned char* out,int count){
00269   int *ri=(int *)in;
00270   int *ibi=(int *)out;
00271   int j,i,k,g;
00272   // copy and first step
00273   for(g=0;g<count;g++){
00274     ri[g]=ibi[2*g];
00275     ri[GROUP_PARALLELISM+g]=ibi[2*g+1];
00276   }
00277 //dump_mem("NE1 r[roff]",&r[roff],GROUP_PARALLELISM*8,GROUP_PARALLELISM);
00278 // now 01230123
00279 #define INTS_PER_ROW (GROUP_PARALLELISM/8*2)
00280   for(j=0;j<8;j+=4){
00281     for(i=0;i<2;i++){
00282       for(k=0;k<INTS_PER_ROW;k++){
00283         unsigned int t,b;
00284         t=ri[INTS_PER_ROW*(j+i)+k];
00285         b=ri[INTS_PER_ROW*(j+i+2)+k];
00286         ri[INTS_PER_ROW*(j+i)+k]=     (t&0x0000ffff)      | ((b           )<<16);
00287         ri[INTS_PER_ROW*(j+i+2)+k]=  ((t           )>>16) |  (b&0xffff0000) ;
00288       }
00289     }
00290   }
00291 //dump_mem("NE2 r[roff]",&r[roff],GROUP_PARALLELISM*8,GROUP_PARALLELISM);
00292 // now 01010101
00293   for(j=0;j<8;j+=2){
00294     for(i=0;i<1;i++){
00295       for(k=0;k<INTS_PER_ROW;k++){
00296         unsigned int t,b;
00297         t=ri[INTS_PER_ROW*(j+i)+k];
00298         b=ri[INTS_PER_ROW*(j+i+1)+k];
00299         ri[INTS_PER_ROW*(j+i)+k]=     (t&0x00ff00ff)     | ((b&0x00ff00ff)<<8);
00300         ri[INTS_PER_ROW*(j+i+1)+k]=  ((t&0xff00ff00)>>8) |  (b&0xff00ff00);
00301       }
00302     }
00303   }
00304 //dump_mem("NE3 r[roff]",&r[roff],GROUP_PARALLELISM*8,GROUP_PARALLELISM);
00305 // now 00000000
00306 }
00307 
00308 static inline __attribute__((always_inline)) void trasp_8_N (unsigned char *in,unsigned char* out,int count){
00309   int *ri=(int *)in;
00310   int *bdi=(int *)out;
00311   int j,i,k,g;
00312 #define INTS_PER_ROW (GROUP_PARALLELISM/8*2)
00313 //dump_mem("NE1 r[roff]",&r[roff],GROUP_PARALLELISM*8,GROUP_PARALLELISM);
00314 // now 00000000
00315   for(j=0;j<8;j+=2){
00316     for(i=0;i<1;i++){
00317       for(k=0;k<INTS_PER_ROW;k++){
00318         unsigned int t,b;
00319         t=ri[INTS_PER_ROW*(j+i)+k];
00320         b=ri[INTS_PER_ROW*(j+i+1)+k];
00321         ri[INTS_PER_ROW*(j+i)+k]=     (t&0x00ff00ff)     | ((b&0x00ff00ff)<<8);
00322         ri[INTS_PER_ROW*(j+i+1)+k]=  ((t&0xff00ff00)>>8) |  (b&0xff00ff00);
00323       }
00324     }
00325   }
00326 //dump_mem("NE2 r[roff]",&r[roff],GROUP_PARALLELISM*8,GROUP_PARALLELISM);
00327 // now 01010101
00328   for(j=0;j<8;j+=4){
00329     for(i=0;i<2;i++){
00330       for(k=0;k<INTS_PER_ROW;k++){
00331         unsigned int t,b;
00332         t=ri[INTS_PER_ROW*(j+i)+k];
00333         b=ri[INTS_PER_ROW*(j+i+2)+k];
00334         ri[INTS_PER_ROW*(j+i)+k]=     (t&0x0000ffff)      | ((b           )<<16);
00335         ri[INTS_PER_ROW*(j+i+2)+k]=  ((t           )>>16) |  (b&0xffff0000) ;
00336       }
00337     }
00338   }
00339 //dump_mem("NE3 r[roff]",&r[roff],GROUP_PARALLELISM*8,GROUP_PARALLELISM);
00340 // now 01230123
00341   for(g=0;g<count;g++){
00342     bdi[2*g]=ri[g];
00343     bdi[2*g+1]=ri[GROUP_PARALLELISM+g];
00344   }
00345 }
00346 
00347 //-----block main function
00348 
00349 // block group
00350 static void block_decypher_group(
00351   batch *kkmulti,       // [In]  kkmulti[0]-kkmulti[55] 56 batches | Key schedule (each batch has repeated equal bytes).
00352   unsigned char *ib,    // [In]  (ib0,ib1,...ib7)...x32 32*8 bytes | Initialization vector.
00353   unsigned char *bd,    // [Out] (bd0,bd1,...bd7)...x32 32*8 bytes | Block decipher.
00354   int count)
00355 {
00356   // int is faster than unsigned char. apparently not
00357   static const unsigned char block_sbox[0x100] = {
00358     0x3A,0xEA,0x68,0xFE,0x33,0xE9,0x88,0x1A, 0x83,0xCF,0xE1,0x7F,0xBA,0xE2,0x38,0x12,
00359     0xE8,0x27,0x61,0x95,0x0C,0x36,0xE5,0x70, 0xA2,0x06,0x82,0x7C,0x17,0xA3,0x26,0x49,
00360     0xBE,0x7A,0x6D,0x47,0xC1,0x51,0x8F,0xF3, 0xCC,0x5B,0x67,0xBD,0xCD,0x18,0x08,0xC9,
00361     0xFF,0x69,0xEF,0x03,0x4E,0x48,0x4A,0x84, 0x3F,0xB4,0x10,0x04,0xDC,0xF5,0x5C,0xC6,
00362     0x16,0xAB,0xAC,0x4C,0xF1,0x6A,0x2F,0x3C, 0x3B,0xD4,0xD5,0x94,0xD0,0xC4,0x63,0x62,
00363     0x71,0xA1,0xF9,0x4F,0x2E,0xAA,0xC5,0x56, 0xE3,0x39,0x93,0xCE,0x65,0x64,0xE4,0x58,
00364     0x6C,0x19,0x42,0x79,0xDD,0xEE,0x96,0xF6, 0x8A,0xEC,0x1E,0x85,0x53,0x45,0xDE,0xBB,
00365     0x7E,0x0A,0x9A,0x13,0x2A,0x9D,0xC2,0x5E, 0x5A,0x1F,0x32,0x35,0x9C,0xA8,0x73,0x30,
00366 
00367     0x29,0x3D,0xE7,0x92,0x87,0x1B,0x2B,0x4B, 0xA5,0x57,0x97,0x40,0x15,0xE6,0xBC,0x0E,
00368     0xEB,0xC3,0x34,0x2D,0xB8,0x44,0x25,0xA4, 0x1C,0xC7,0x23,0xED,0x90,0x6E,0x50,0x00,
00369     0x99,0x9E,0x4D,0xD9,0xDA,0x8D,0x6F,0x5F, 0x3E,0xD7,0x21,0x74,0x86,0xDF,0x6B,0x05,
00370     0x8E,0x5D,0x37,0x11,0xD2,0x28,0x75,0xD6, 0xA7,0x77,0x24,0xBF,0xF0,0xB0,0x02,0xB7,
00371     0xF8,0xFC,0x81,0x09,0xB1,0x01,0x76,0x91, 0x7D,0x0F,0xC8,0xA0,0xF2,0xCB,0x78,0x60,
00372     0xD1,0xF7,0xE0,0xB5,0x98,0x22,0xB3,0x20, 0x1D,0xA6,0xDB,0x7B,0x59,0x9F,0xAE,0x31,
00373     0xFB,0xD3,0xB6,0xCA,0x43,0x72,0x07,0xF4, 0xD8,0x41,0x14,0x55,0x0D,0x54,0x8B,0xB9,
00374     0xAD,0x46,0x0B,0xAF,0x80,0x52,0x2C,0xFA, 0x8C,0x89,0x66,0xFD,0xB2,0xA9,0x9B,0xC0,
00375   };
00376   MEMALIGN unsigned char r[GROUP_PARALLELISM*(8+56)];  /* 56 because we will move back in memory while looping */
00377   MEMALIGN unsigned char sbox_in[GROUP_PARALLELISM],sbox_out[GROUP_PARALLELISM],perm_out[GROUP_PARALLELISM];
00378   int roff;
00379   int i,g,count_all=GROUP_PARALLELISM;
00380 
00381   roff=GROUP_PARALLELISM*56;
00382 
00383 #define FASTTRASP1
00384 #ifndef FASTTRASP1
00385   for(g=0;g<count;g++){
00386     // Init registers 
00387     int j;
00388     for(j=0;j<8;j++){
00389       r[roff+GROUP_PARALLELISM*j+g]=ib[8*g+j];
00390     }
00391   }
00392 #else
00393   trasp_N_8((unsigned char *)&r[roff],(unsigned char *)ib,count);
00394 #endif
00395 //dump_mem("OLD r[roff]",&r[roff],GROUP_PARALLELISM*8,GROUP_PARALLELISM);
00396 
00397   // loop over kk[55]..kk[0]
00398   for(i=55;i>=0;i--){
00399     {
00400       MEMALIGN batch tkkmulti=kkmulti[i];
00401       batch *si=(batch *)sbox_in;
00402       batch *r6_N=(batch *)(r+roff+GROUP_PARALLELISM*6);
00403       for(g=0;g<count_all/BYTES_PER_BATCH;g++){
00404         si[g]=B_FFXOR(tkkmulti,r6_N[g]);              //FIXME: introduce FASTBATCH?
00405       }
00406     }
00407 
00408     // table lookup, this works on only one byte at a time
00409     // most difficult part of all
00410     // - can't be parallelized
00411     // - can't be synthetized through boolean terms (8 input bits are too many)
00412     for(g=0;g<count_all;g++){
00413       sbox_out[g]=block_sbox[sbox_in[g]];
00414     }
00415 
00416     // bit permutation
00417     {
00418       unsigned char *po=(unsigned char *)perm_out;
00419       unsigned char *so=(unsigned char *)sbox_out;
00420 //dump_mem("pre perm ",(unsigned char *)so,GROUP_PARALLELISM,GROUP_PARALLELISM);
00421       for(g=0;g<count_all;g+=BYTES_PER_BATCH){
00422         MEMALIGN batch in,out;
00423         in=*(batch *)&so[g];
00424 
00425         out=B_FFOR(
00426             B_FFOR(
00427             B_FFOR(
00428             B_FFOR(
00429             B_FFOR(
00430                    B_FFSH8L(B_FFAND(in,B_FFN_ALL_29()),1),
00431                    B_FFSH8L(B_FFAND(in,B_FFN_ALL_02()),6)),
00432                    B_FFSH8L(B_FFAND(in,B_FFN_ALL_04()),3)),
00433                    B_FFSH8R(B_FFAND(in,B_FFN_ALL_10()),2)),
00434                    B_FFSH8R(B_FFAND(in,B_FFN_ALL_40()),6)),
00435                    B_FFSH8R(B_FFAND(in,B_FFN_ALL_80()),4));
00436 
00437         *(batch *)&po[g]=out;
00438       }
00439 //dump_mem("post perm",(unsigned char *)po,GROUP_PARALLELISM,GROUP_PARALLELISM);
00440     }
00441 
00442     roff-=GROUP_PARALLELISM; /* virtual shift of registers */
00443 
00444 #if 0
00445 /* one by one */
00446     for(g=0;g<count_all;g++){
00447       r[roff+GROUP_PARALLELISM*0+g]=r[roff+GROUP_PARALLELISM*8+g]^sbox_out[g];
00448       r[roff+GROUP_PARALLELISM*6+g]^=perm_out[g];
00449       r[roff+GROUP_PARALLELISM*4+g]^=r[roff+GROUP_PARALLELISM*0+g];
00450       r[roff+GROUP_PARALLELISM*3+g]^=r[roff+GROUP_PARALLELISM*0+g];
00451       r[roff+GROUP_PARALLELISM*2+g]^=r[roff+GROUP_PARALLELISM*0+g];
00452     }
00453 #else
00454     for(g=0;g<count_all;g+=BEST_SPAN){
00455       XOR_BEST_BY(&r[roff+GROUP_PARALLELISM*0+g],&r[roff+GROUP_PARALLELISM*8+g],&sbox_out[g]);
00456       XOREQ_BEST_BY(&r[roff+GROUP_PARALLELISM*6+g],&perm_out[g]);
00457       XOREQ_BEST_BY(&r[roff+GROUP_PARALLELISM*4+g],&r[roff+GROUP_PARALLELISM*0+g]);
00458       XOREQ_BEST_BY(&r[roff+GROUP_PARALLELISM*3+g],&r[roff+GROUP_PARALLELISM*0+g]);
00459       XOREQ_BEST_BY(&r[roff+GROUP_PARALLELISM*2+g],&r[roff+GROUP_PARALLELISM*0+g]);
00460     }
00461 #endif
00462   }
00463 
00464 #define FASTTRASP2
00465 #ifndef FASTTRASP2
00466   for(g=0;g<count;g++){
00467     // Copy results
00468     int j;
00469     for(j=0;j<8;j++){
00470       bd[8*g+j]=r[roff+GROUP_PARALLELISM*j+g];
00471     }
00472   }
00473 #else
00474   trasp_8_N((unsigned char *)&r[roff],(unsigned char *)bd,count);
00475 #endif
00476 }
00477 
00478 //-----------------------------------EXTERNAL INTERFACE
00479 
00480 //-----get internal parallelism
00481 
00482 int get_internal_parallelism(void){
00483   return GROUP_PARALLELISM;
00484 }
00485 
00486 //-----get suggested cluster size
00487 
00488 int get_suggested_cluster_size(void){
00489   int r;
00490   r=GROUP_PARALLELISM+GROUP_PARALLELISM/10;
00491   if(r<GROUP_PARALLELISM+5) r=GROUP_PARALLELISM+5;
00492   return r;
00493 }
00494 
00495 //-----key structure
00496 
00497 void *get_key_struct(void){
00498   struct csa_keys_t *keys=(struct csa_keys_t *)MALLOC(sizeof(struct csa_keys_t));
00499   if(keys) {
00500     static const unsigned char pk[8] = { 0,0,0,0,0,0,0,0 };
00501     set_control_words(keys,pk,pk);
00502     }
00503   return keys;
00504 }
00505 
00506 void free_key_struct(void *keys){
00507   return FREE(keys);
00508 }
00509 
00510 //-----set control words
00511 
00512 static void schedule_key(struct csa_key_t *key, const unsigned char *pk){
00513   // could be made faster, but is not run often
00514   int bi,by;
00515   int i,j;
00516 // key
00517   memcpy(key->ck,pk,8);
00518 // precalculations for stream
00519   key_schedule_stream(key->ck,key->iA,key->iB);
00520   for(by=0;by<8;by++){
00521     for(bi=0;bi<8;bi++){
00522       key->ck_g[by][bi]=(key->ck[by]&(1<<bi))?FF1():FF0();
00523     }
00524   }
00525   for(by=0;by<8;by++){
00526     for(bi=0;bi<4;bi++){
00527       key->iA_g[by][bi]=(key->iA[by]&(1<<bi))?FF1():FF0();
00528       key->iB_g[by][bi]=(key->iB[by]&(1<<bi))?FF1():FF0();
00529     }
00530   }
00531 // precalculations for block
00532   key_schedule_block(key->ck,key->kk);
00533   for(i=0;i<56;i++){
00534     for(j=0;j<BYTES_PER_BATCH;j++){
00535       *(((unsigned char *)&key->kkmulti[i])+j)=key->kk[i];
00536     }
00537   }
00538 }
00539 
00540 void set_control_words(void *keys, const unsigned char *ev, const unsigned char *od){
00541   schedule_key(&((struct csa_keys_t *)keys)->even,ev);
00542   schedule_key(&((struct csa_keys_t *)keys)->odd,od);
00543 }
00544 
00545 void set_even_control_word(void *keys, const unsigned char *pk){
00546   schedule_key(&((struct csa_keys_t *)keys)->even,pk);
00547 }
00548 
00549 void set_odd_control_word(void *keys, const unsigned char *pk){
00550   schedule_key(&((struct csa_keys_t *)keys)->odd,pk);
00551 }
00552 
00553 //-----get control words
00554 
00555 void get_control_words(void *keys, unsigned char *even, unsigned char *odd){
00556   memcpy(even,&((struct csa_keys_t *)keys)->even.ck,8);
00557   memcpy(odd,&((struct csa_keys_t *)keys)->odd.ck,8);
00558 }
00559 
00560 //----- decrypt
00561 
00562 int decrypt_packets(void *keys, unsigned char **cluster){
00563   // statistics, currently unused
00564   int stat_no_scramble=0;
00565   int stat_reserved=0;
00566   int stat_decrypted[2]={0,0};
00567   int stat_decrypted_mini=0;
00568   unsigned char **clst;
00569   unsigned char **clst2;
00570   int grouped;
00571   int group_ev_od;
00572   int advanced;
00573   int can_advance;
00574   unsigned char *g_pkt[GROUP_PARALLELISM];
00575   int g_len[GROUP_PARALLELISM];
00576   int g_offset[GROUP_PARALLELISM];
00577   int g_n[GROUP_PARALLELISM];
00578   int g_residue[GROUP_PARALLELISM];
00579   unsigned char *pkt;
00580   int xc0,ev_od,len,offset,n,residue;
00581   struct csa_key_t* k;
00582   int i,j,iter,g;
00583   int t23,tsmall;
00584   int alive[24];
00585 //icc craziness  int pad1=0; //////////align! FIXME
00586   unsigned char *encp[GROUP_PARALLELISM];
00587   MEMALIGN unsigned char stream_in[GROUP_PARALLELISM*8];
00588   MEMALIGN unsigned char stream_out[GROUP_PARALLELISM*8];
00589   MEMALIGN unsigned char ib[GROUP_PARALLELISM*8];
00590   MEMALIGN unsigned char block_out[GROUP_PARALLELISM*8];
00591 #ifdef COPY_UNALIGNED_PKT
00592   unsigned char *unaligned[GROUP_PARALLELISM];
00593   MEMALIGN unsigned char alignedBuff[GROUP_PARALLELISM][188];
00594 #endif
00595   struct stream_regs regs;
00596 
00597 //icc craziness  i=(int)&pad1;//////////align!!! FIXME
00598 
00599   // build a list of packets to be processed
00600   clst=cluster;
00601   grouped=0;
00602   advanced=0;
00603   can_advance=1;
00604   group_ev_od=-1; // silence incorrect compiler warning
00605   pkt=*clst;
00606   do{ // find a new packet
00607     if(grouped==GROUP_PARALLELISM){
00608       // full
00609       break;
00610     }
00611     if(pkt==NULL){
00612       // no more ranges
00613       break;
00614     }
00615     if(pkt>=*(clst+1)){
00616       // out of this range, try next
00617       clst++;clst++;
00618       pkt=*clst;
00619       continue;
00620     }
00621 
00622     do{ // handle this packet
00623       xc0=pkt[3]&0xc0;
00624       DBG(fprintf(stderr,"   exam pkt=%p, xc0=%02x, can_adv=%i\n",pkt,xc0,can_advance));
00625       if(xc0==0x00){
00626         DBG(fprintf(stderr,"skip clear pkt %p (can_advance is %i)\n",pkt,can_advance));
00627         advanced+=can_advance;
00628         stat_no_scramble++;
00629         break;
00630       }
00631       if(xc0==0x40){
00632         DBG(fprintf(stderr,"skip reserved pkt %p (can_advance is %i)\n",pkt,can_advance));
00633         advanced+=can_advance;
00634         stat_reserved++;
00635         break;
00636       }
00637       if(xc0==0x80||xc0==0xc0){ // encrypted
00638         ev_od=(xc0&0x40)>>6; // 0 even, 1 odd
00639         if(grouped==0) group_ev_od=ev_od; // this group will be all even (or odd)
00640         if(group_ev_od==ev_od){ // could be added to group
00641           pkt[3]&=0x3f;  // consider it decrypted now
00642           if(pkt[3]&0x20){ // incomplete packet
00643             offset=4+pkt[4]+1;
00644             len=188-offset;
00645             n=len>>3;
00646             residue=len-(n<<3);
00647             if(n==0){ // decrypted==encrypted!
00648               DBG(fprintf(stderr,"DECRYPTED MINI! (can_advance is %i)\n",can_advance));
00649               advanced+=can_advance;
00650               stat_decrypted_mini++;
00651               break; // this doesn't need more processing
00652             }
00653           }else{
00654             len=184;
00655             offset=4;
00656             n=23;
00657             residue=0;
00658           }
00659           g_pkt[grouped]=pkt;
00660           g_len[grouped]=len;
00661           g_offset[grouped]=offset;
00662           g_n[grouped]=n;
00663           g_residue[grouped]=residue;
00664           DBG(fprintf(stderr,"%2i: eo=%i pkt=%p len=%03i n=%2i residue=%i\n",grouped,ev_od,pkt,len,n,residue));
00665           grouped++;
00666           advanced+=can_advance;
00667           stat_decrypted[ev_od]++;
00668         }
00669         else{
00670           can_advance=0;
00671           DBG(fprintf(stderr,"skip pkt %p and can_advance set to 0\n",pkt));
00672           break; // skip and go on
00673         }
00674       }
00675     } while(0);
00676 
00677     if(can_advance){
00678       // move range start forward
00679       *clst+=188;
00680     }
00681     // next packet, if there is one
00682     pkt+=188;
00683   } while(1);
00684   DBG(fprintf(stderr,"-- result: grouped %i pkts, advanced %i pkts\n",grouped,advanced));
00685 
00686   // delete empty ranges and compact list
00687   clst2=cluster;
00688   for(clst=cluster;*clst!=NULL;clst+=2){
00689     // if not empty
00690     if(*clst<*(clst+1)){
00691       // it will remain 
00692       *clst2=*clst;
00693       *(clst2+1)=*(clst+1);
00694       clst2+=2;
00695     }
00696   }
00697   *clst2=NULL;
00698 
00699   if(grouped==0){
00700     // no processing needed
00701     return advanced;
00702   }
00703 
00704   //  sort them, longest payload first
00705   //  we expect many n=23 packets and a few n<23
00706   DBG(fprintf(stderr,"PRESORTING\n"));
00707   for(i=0;i<grouped;i++){
00708     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]));
00709     }
00710   // grouped is always <= GROUP_PARALLELISM
00711 
00712 #define g_swap(a,b) \
00713     pkt=g_pkt[a]; \
00714     g_pkt[a]=g_pkt[b]; \
00715     g_pkt[b]=pkt; \
00716 \
00717     len=g_len[a]; \
00718     g_len[a]=g_len[b]; \
00719     g_len[b]=len; \
00720 \
00721     offset=g_offset[a]; \
00722     g_offset[a]=g_offset[b]; \
00723     g_offset[b]=offset; \
00724 \
00725     n=g_n[a]; \
00726     g_n[a]=g_n[b]; \
00727     g_n[b]=n; \
00728 \
00729     residue=g_residue[a]; \
00730     g_residue[a]=g_residue[b]; \
00731     g_residue[b]=residue;
00732 
00733   // step 1: move n=23 packets before small packets
00734   t23=0;
00735   tsmall=grouped-1;
00736   for(;;){
00737     for(;t23<grouped;t23++){
00738       if(g_n[t23]!=23) break;
00739     }
00740 DBG(fprintf(stderr,"t23 after for =%i\n",t23));
00741     
00742     for(;tsmall>=0;tsmall--){
00743       if(g_n[tsmall]==23) break;
00744     }
00745 DBG(fprintf(stderr,"tsmall after for =%i\n",tsmall));
00746     
00747     if(tsmall-t23<1) break;
00748     
00749 DBG(fprintf(stderr,"swap t23=%i,tsmall=%i\n",t23,tsmall));
00750 
00751     g_swap(t23,tsmall);
00752 
00753     t23++;
00754     tsmall--;
00755 DBG(fprintf(stderr,"new t23=%i,tsmall=%i\n\n",t23,tsmall));
00756   }
00757   DBG(fprintf(stderr,"packets with n=23, t23=%i   grouped=%i\n",t23,grouped));
00758   DBG(fprintf(stderr,"MIDSORTING\n"));
00759   for(i=0;i<grouped;i++){
00760     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]));
00761     }
00762 
00763   // step 2: sort small packets in decreasing order of n (bubble sort is enough)
00764   for(i=t23;i<grouped;i++){
00765     for(j=i+1;j<grouped;j++){
00766       if(g_n[j]>g_n[i]){
00767         g_swap(i,j);
00768       }
00769     }
00770   }
00771   DBG(fprintf(stderr,"POSTSORTING\n"));
00772   for(i=0;i<grouped;i++){
00773     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]));
00774     }
00775 
00776   // we need to know how many packets need 23 iterations, how many 22...
00777   for(i=0;i<=23;i++){
00778     alive[i]=0;
00779   }
00780   // count
00781   alive[23-1]=t23;
00782   for(i=t23;i<grouped;i++){
00783     alive[g_n[i]-1]++;
00784   }
00785   // integrate
00786   for(i=22;i>=0;i--){
00787     alive[i]+=alive[i+1];
00788   }
00789   DBG(fprintf(stderr,"ALIVE\n"));
00790   for(i=0;i<=23;i++){
00791     DBG(fprintf(stderr,"alive%2i=%i\n",i,alive[i]));
00792     }
00793 
00794   // choose key
00795   if(group_ev_od==0){
00796     k=&((struct csa_keys_t *)keys)->even;
00797   }
00798   else{
00799     k=&((struct csa_keys_t *)keys)->odd;
00800   }
00801 
00802   //INIT
00803 //#define INITIALIZE_UNUSED_INPUT
00804 #ifdef INITIALIZE_UNUSED_INPUT
00805 // unnecessary zeroing.
00806 // without this, we operate on uninitialized memory
00807 // when grouped<GROUP_PARALLELISM, but it's not a problem,
00808 // as final results will be discarded.
00809 // random data makes debugging sessions difficult.
00810   for(j=0;j<GROUP_PARALLELISM*8;j++) stream_in[j]=0;
00811 DBG(fprintf(stderr,"--- WARNING: you could gain speed by not initializing unused memory ---\n"));
00812 #else
00813 DBG(fprintf(stderr,"--- WARNING: DEBUGGING IS MORE DIFFICULT WHEN PROCESSING RANDOM DATA CHANGING AT EVERY RUN! ---\n"));
00814 #endif
00815 
00816   for(g=0;g<grouped;g++){
00817     encp[g]=g_pkt[g];
00818     DBG(fprintf(stderr,"header[%i]=%p (%02x)\n",g,encp[g],*(encp[g])));
00819     encp[g]+=g_offset[g]; // skip header
00820 #ifdef COPY_UNALIGNED_PKT
00821     if(((int)encp[g])&0x03) {
00822       memcpy(alignedBuff[g],encp[g],g_len[g]);
00823       unaligned[g]=encp[g];
00824       encp[g]=alignedBuff[g];
00825       }
00826     else unaligned[g]=0;
00827 #endif
00828     FFTABLEIN(stream_in,g,encp[g]);
00829   }
00830 //dump_mem("stream_in",stream_in,GROUP_PARALLELISM*8,BYPG);
00831 
00832 
00833   // ITER 0
00834 DBG(fprintf(stderr,">>>>>ITER 0\n"));
00835   iter=0;
00836   stream_cypher_group_init(&regs,k->iA_g,k->iB_g,stream_in);
00837   // fill first ib
00838   for(g=0;g<alive[iter];g++){
00839     COPY_8_BY(ib+8*g,encp[g]);
00840   }
00841 DBG(dump_mem("IB ",ib,8*alive[iter],8));
00842   // ITER 1..N-1
00843   for (iter=1;iter<23&&alive[iter-1]>0;iter++){
00844 DBG(fprintf(stderr,">>>>>ITER %i\n",iter));
00845     // alive and just dead packets: calc block
00846     block_decypher_group(k->kkmulti,ib,block_out,alive[iter-1]);
00847 DBG(dump_mem("BLO_ib ",block_out,8*alive[iter-1],8));
00848     // all packets (dead too): calc stream
00849     stream_cypher_group_normal(&regs,stream_out);
00850 //dump_mem("stream_out",stream_out,GROUP_PARALLELISM*8,BYPG);
00851 
00852     // alive packets: calc ib
00853     for(g=0;g<alive[iter];g++){
00854       FFTABLEOUT(ib+8*g,stream_out,g);
00855 DBG(dump_mem("stream_out_ib ",ib+8*g,8,8));
00856 // XOREQ8BY gcc bug? 2x4 ok, 8 ko    UPDATE: result ok but speed 1-2% slower (!!!???)
00857 #if 1
00858       XOREQ_4_BY(ib+8*g,encp[g]+8);
00859       XOREQ_4_BY(ib+8*g+4,encp[g]+8+4);
00860 #else
00861       XOREQ_8_BY(ib+8*g,encp[g]+8);
00862 #endif
00863 DBG(dump_mem("after_stream_xor_ib ",ib+8*g,8,8));
00864     }
00865     // alive packets: decrypt data
00866     for(g=0;g<alive[iter];g++){
00867 DBG(dump_mem("before_ib_decrypt_data ",encp[g],8,8));
00868       XOR_8_BY(encp[g],ib+8*g,block_out+8*g);
00869 DBG(dump_mem("after_ib_decrypt_data ",encp[g],8,8));
00870     }
00871     // just dead packets: write decrypted data
00872     for(g=alive[iter];g<alive[iter-1];g++){
00873 DBG(dump_mem("jd_before_ib_decrypt_data ",encp[g],8,8));
00874       COPY_8_BY(encp[g],block_out+8*g);
00875 DBG(dump_mem("jd_after_ib_decrypt_data ",encp[g],8,8));
00876     }
00877     // just dead packets: decrypt residue
00878     for(g=alive[iter];g<alive[iter-1];g++){
00879 DBG(dump_mem("jd_before_decrypt_residue ",encp[g]+8,g_residue[g],g_residue[g]));
00880       FFTABLEOUTXORNBY(g_residue[g],encp[g]+8,stream_out,g);
00881 DBG(dump_mem("jd_after_decrypt_residue ",encp[g]+8,g_residue[g],g_residue[g]));
00882     }
00883     // alive packets: pointers++
00884     for(g=0;g<alive[iter];g++) encp[g]+=8;
00885   };
00886   // ITER N
00887 DBG(fprintf(stderr,">>>>>ITER 23\n"));
00888   iter=23;
00889   // calc block
00890   block_decypher_group(k->kkmulti,ib,block_out,alive[iter-1]);
00891 DBG(dump_mem("23BLO_ib ",block_out,8*alive[iter-1],8));
00892   // just dead packets: write decrypted data
00893   for(g=alive[iter];g<alive[iter-1];g++){
00894 DBG(dump_mem("23jd_before_ib_decrypt_data ",encp[g],8,8));
00895     COPY_8_BY(encp[g],block_out+8*g);
00896 DBG(dump_mem("23jd_after_ib_decrypt_data ",encp[g],8,8));
00897   }
00898   // no residue possible
00899   // so do nothing
00900 
00901   DBG(fprintf(stderr,"returning advanced=%i\n",advanced));
00902 
00903 #ifdef COPY_UNALIGNED_PKT
00904   for(g=0;g<grouped;g++)
00905     if(unaligned[g]) memcpy(unaligned[g],alignedBuff[g],g_len[g]);
00906 #endif
00907 
00908   M_EMPTY(); // restore CPU multimedia state
00909 
00910   return advanced;
00911 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines