|
SASC-NG
DVBSoftCAM
|
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(®s,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(®s,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 }