diff -ruN sc-0.8.7/common.h sc-src/common.h --- sc-0.8.7/common.h 1969-12-31 19:00:00.000000000 -0500 +++ sc-src/common.h 2008-02-06 16:49:45.000000000 -0500 @@ -0,0 +1,40 @@ +/* + * Softcam plugin to VDR (C++) + * + * This code is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * Or, point your browser to http://www.gnu.org/copyleft/gpl.html + */ + +#ifndef ___COMMON_H +#define ___COMMON_H + +// Debugging +#define DEBUG +//#define DEBUG_DYN +#define DEBUG_LOG_FILE "/var/tmp/logger.log" + +#ifdef DEBUG +#define d(x) { (x); } +#else +#define d(x) ; +#endif + +#ifdef DEBUG_DYN +#define dyn(x) { (x); } +#else +#define dyn(x) ; +#endif + +#endif //___COMMON_H diff -ruN sc-0.8.7/systems/nagra/nagra2-0101.c sc-src/systems/nagra/nagra2-0101.c --- sc-0.8.7/systems/nagra/nagra2-0101.c 2008-01-15 16:17:29.000000000 -0500 +++ sc-src/systems/nagra/nagra2-0101.c 2008-02-06 16:49:45.000000000 -0500 @@ -435,6 +435,16 @@ else cycles=931 + 4*coef22[shift][0] - 6; break; } + case 0x29: + { + BN_add(B, B, C); + if(l<=0) l = wordsize; + bool b = BN_is_bit_set(B, l<<6); + if(data) data[0] = b; + if(b) BN_mask_bits(B, l<<6); + cycles = 504+(8*l)-((8*l-2)%5)-6; + } + break; case 0x3b: if(!l) l=wordsize; MonInit(wordsize*60+4*l); @@ -619,11 +629,12 @@ SetSp(0x0FFF,0x0EF8); ClearBreakpoints(); SetMem(0x0100,mecmCode+8,0x100-8); + SetMem(0xa00,hd,seedSize); SetMem(0x0ba2,hw,0x80); AddBreakpoint(0x0000); AddRomCallbacks(); SetPc(0x0100); - while(!Run(10000)) { + while(!Run(100000)) { if(GetPc()==0x0000) { GetMem(0x0ba2,hw,0x80); return true; @@ -755,6 +766,11 @@ DoMap(f,tmp,-((Get(0x48)<<16)|(Get(0x49)<<8)|Get(0x4a))); AddCycles(MapCycles()); break; + case 0x29: + DoMap(f,tmp,-Get(0x48)); + Set(0x00, 0x4b, *tmp); + AddCycles(MapCycles()); + break; case 0x3b: size=Get(0x48); if(!size) size=wordsize; GetMem(HILO(0x44),tmp,size<<3,0); @@ -765,6 +781,19 @@ DoMap(f,tmp,Get(0x48)); AddCycles(MapCycles()); break; + case 0x43: + DoMap(f, NULL); + break; + case 0x44: + GetMem(0x400, tmp, 0x40, 0); + DoMap(f,tmp); + SetMem(0x440, tmp, 0x14, 0); + break; + case 0x45: + GetMem(0x400, tmp, 0x40, 0); + DoMap(f,tmp,Get(0x48)); + SetMem(0x440, tmp, 0x14, 0); + break; case 0x4d: DoMap(f,tmp,-((Get(0x48)<<16)|(Get(0x49)<<8)|Get(0x4a))); SetMem(0x400,tmp,53,0); @@ -972,7 +1001,6 @@ return 1; } else if(!RomCallbacks()) break; - break; } } return -1; diff -ruN sc-0.8.7/systems/nagra/nagra2.c sc-src/systems/nagra/nagra2.c --- sc-0.8.7/systems/nagra/nagra2.c 2008-01-15 16:14:33.000000000 -0500 +++ sc-src/systems/nagra/nagra2.c 2008-02-06 16:49:45.000000000 -0500 @@ -502,22 +502,22 @@ case CLEAR_B: case CLEAR_C: case CLEAR_D: - cycles=467+5*l1-6; + cycles=465+(8*l1)-((8*l1-2)%5)-6; last=f-CLEAR_A+1; BN_zero(*regs[last]); break; case COPY_A_B: - last=2; BN_copy(B,A); cycles=467+5*l1-6; break; + last=2; BN_copy(B,A); cycles=465+(8*l1)-((8*l1-2)%5)-6; break; case COPY_B_A: - last=1; BN_copy(A,B); cycles=467+5*l1-6; break; + last=1; BN_copy(A,B); cycles=465+(8*l1)-((8*l1-2)%5)-6; break; case COPY_A_C: - last=3; BN_copy(C,A); cycles=467+5*l1-6; break; + last=3; BN_copy(C,A); cycles=465+(8*l1)-((8*l1-2)%5)-6; break; case COPY_C_A: - last=1; BN_copy(A,C); cycles=467+5*l1-6; break; + last=1; BN_copy(A,C); cycles=465+(8*l1)-((8*l1-2)%5)-6; break; case COPY_C_D: - last=4; BN_copy(D,C); cycles=467+5*l1-6; break; + last=4; BN_copy(D,C); cycles=465+(8*l1)-((8*l1-2)%5)-6; break; case COPY_D_C: - last=3; BN_copy(C,D); cycles=467+5*l1-6; break; + last=3; BN_copy(C,D); cycles=465+(8*l1)-((8*l1-2)%5)-6; break; case 0x43: // init SHA1 SHA1_Init(&sctx); @@ -532,12 +532,17 @@ BYTE4_LE(data+16,sctx.h0); break; case 0x45: // add wordsize bytes to SHA1 buffer and finalize SHA result - if(wordsize) { - if(wordsize>1) RotateBytes(data,wordsize); - SHA1_Update(&sctx,data,wordsize); + if(dl) { + if(dl>1) RotateBytes(data,dl); + SHA1_Update(&sctx,data,dl); } memset(data,0,64); SHA1_Final(data+64,&sctx); + BYTE4_LE(data ,sctx.h4); + BYTE4_LE(data+4 ,sctx.h3); + BYTE4_LE(data+8 ,sctx.h2); + BYTE4_LE(data+12,sctx.h1); + BYTE4_LE(data+16,sctx.h0); break; default: return false; @@ -816,8 +821,10 @@ #define NA_SOURCE_END 0x85c8 // cSource::FromString("S148W"); unsigned char odata[15]; memcpy(odata,data,sizeof(odata)); + HEXDUMP(L_SYS_RAWECM,data,SCT_LEN(data),"Nagra2 Encrypted ECM"); if(ecm->source>=NA_SOURCE_START && ecm->source<=NA_SOURCE_END) { if(ecm->caId==0x1234) data[5]=0x09; // NA rev 248 morph + else if (ecm->caId==0x1801 && ecm->source==0x83ca) data[5]=0xC1; //Galaxy 97 hack else data[5]=0x01; // I _HATE_ this provider data[6]&=0x1F; // specific stuff :( data[7]=data[7]&0x10|0x86; @@ -975,6 +982,7 @@ } lastEmmId=id; + HEXDUMP(L_SYS_RAWEMM,buffer,SCT_LEN(buffer),"Nagra2 Encrypted EMM"); HEXDUMP(L_SYS_RAWEMM,emmdata,cmdLen,"Nagra2 RAWEMM"); id=(emmdata[8]<<8)+emmdata[9]; LBSTARTF(L_SYS_EMM); diff -ruN sc-0.8.7/systems/nagra/nagra2-map57.c sc-src/systems/nagra/nagra2-map57.c --- sc-0.8.7/systems/nagra/nagra2-map57.c 1969-12-31 19:00:00.000000000 -0500 +++ sc-src/systems/nagra/nagra2-map57.c 2008-02-06 16:49:45.000000000 -0500 @@ -0,0 +1,677 @@ +/* + * Softcam plugin to VDR (C++) + * + * This code is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * Or, point your browser to http://www.gnu.org/copyleft/gpl.html + */ + +// -- cN2Map57 ---------------------------------------------------------------- + +class cN2Map57 { +private: + void mod_add(BIGNUM *arg1, BIGNUM *arg2, BIGNUM *arg3, BIGNUM *arg4); + void bn_cmplx1(BIGNUM *arg1, BIGNUM *arg2, BIGNUM *arg3, BIGNUM *arg4, BIGNUM *arg5); + void bn_cmplx1a(BIGNUM *arg1, BIGNUM *arg2, BIGNUM *arg3, BIGNUM *arg4, BIGNUM *arg5); + void mod_sub(void); + void bn_func1(BIGNUM *arg0); + void bn_func2(int arg0); + void bn_func3(int arg0); + void bn_cmplx7(void); + void bn_cmplx2(BIGNUM *var1, BIGNUM *var2, BIGNUM *var3, BIGNUM *var4, BIGNUM *var5, BIGNUM *var6); + BIGNUM *bn_glb0, *bn_glb1, *bn_glb3, *bn_glb5, *bn_glb6, *bn_glb7; + BIGNUM *bn_glb_a, *bn_glb_b, *bn_glb_c, *bn_glb_d, *bn_glb_e, *bn_glb_f, *bn_glb_g; + BIGNUM *bn_glb_h, *bn_glb_i, *bn_glb_j, *bn_glb_k, *bn_glb_l, *bn_glb_m; + BIGNUM *glb2pow128, *mask128, *glb2pow64, *mask64; + BN_CTX *t1; +public: + void Map57(unsigned char *data); + }; + +void cN2Map57::mod_add(BIGNUM *arg1, BIGNUM *arg2, BIGNUM *arg3, BIGNUM *arg4) +{ + BN_add(arg1, arg2, arg3); + if(BN_cmp(arg1, arg4) >= 0) { + BN_sub(arg1, arg1, arg4); + } + BN_mask_bits(arg1, 128); +} + +void cN2Map57::bn_cmplx1(BIGNUM *arg1, BIGNUM *arg2, BIGNUM *arg3, BIGNUM *arg4, BIGNUM *arg5) +{ + int j; + BIGNUM *var44, *var64, *var84, *vara4; + var44 = BN_new(); + var64 = BN_new(); + var84 = BN_new(); + vara4 = BN_new(); + BN_copy(var44, arg2); + BN_copy(var64, arg3); + BN_clear(vara4); + for(j=0; j<2; j++) { + BN_copy(var84, var64); + BN_mask_bits(var84, 64); + BN_rshift(var64, var64, 64); + BN_mul(var84, var84, var44, t1); + BN_add(vara4, vara4, var84); + BN_copy(var84, vara4); + BN_mask_bits(var84, 128); + BN_mul(var84, vara4, arg4, t1); + BN_mask_bits(var84, 64); + BN_mul(var84, var84, arg5, t1); + BN_add(vara4, vara4, var84); + BN_rshift(vara4, vara4, 64); + if(BN_cmp(vara4, arg5) >= 0) { + BN_sub(vara4, vara4, arg5); + } + BN_mask_bits(vara4, 128); + } + BN_copy(arg1, vara4); + BN_free(var44); + BN_free(var64); + BN_free(var84); + BN_free(vara4); +} + +void cN2Map57::bn_cmplx1a(BIGNUM *arg1, BIGNUM *arg2, BIGNUM *arg3, BIGNUM *arg4, BIGNUM *arg5) +{ + int j; + BIGNUM *var44, *var64, *var84, *vara4; + var44 = BN_new(); + var64 = BN_new(); + var84 = BN_new(); + vara4 = BN_new(); + BN_copy(var44, arg2); + BN_copy(var64, arg3); + BN_clear(vara4); + for(j=0; j<2; j++) { + BN_copy(var84, var64); + BN_mask_bits(var84, 64); + BN_rshift(var64, var64, 64); + BN_mul(var84, var84, var44, t1); + BN_add(vara4, vara4, var84); + BN_copy(var84, vara4); + BN_mask_bits(var84, 128); + BN_mul(var84, vara4, arg4, t1); + BN_mask_bits(var84, 64); + BN_mul(var84, var84, arg5, t1); + BN_add(vara4, vara4, var84); + BN_rshift(vara4, vara4, 64); + if(j==0 && BN_cmp(vara4, arg5) >= 0) { + BN_sub(vara4, vara4, arg5); + } + BN_mask_bits(vara4, 128); + } + BN_copy(arg1, vara4); + BN_free(var44); + BN_free(var64); + BN_free(var84); + BN_free(vara4); +} + +//uses 3, 1, glb2pow128 +//sets 1, 0 (unused) +void cN2Map57::mod_sub() +{ + BN_copy(bn_glb0, bn_glb3); + BN_mod_sub(bn_glb1, bn_glb3, bn_glb1, glb2pow128, t1); + BN_mask_bits(bn_glb1, 128); +} + +//uses 1, 3, 6 +//sets 1, 0 (unused), 7(unused) +void cN2Map57::bn_func1(BIGNUM *arg0) +{ + BIGNUM *var30 = BN_new(); + BIGNUM *var50 = BN_new(); + BN_copy(var30,arg0); + BN_mask_bits(var30, 8); + unsigned int x = BN_get_word(var30); + BN_copy(var30,arg0); + if( x != 0) { + BN_clear(var50); + BN_set_word(var50, 2); + BN_sub(var30, var30, var50); + } else { + BN_clear(var50); + BN_set_word(var50, 0xfe); + BN_add(var30, var30, var50); + } + BN_copy(bn_glb7, bn_glb1); + if(BN_is_zero(arg0)) { + BN_clear(bn_glb7); + BN_set_word(bn_glb7, 1); + BN_clear(bn_glb0); + + mod_add(bn_glb1, bn_glb7, bn_glb0, bn_glb3); + BN_free(var30); + BN_free(var50); + return; + } else { + int msb = BN_num_bits(var30) -1; + while (msb > 0) { + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb1, bn_glb6, bn_glb3); + msb--; + if(BN_is_bit_set(var30, msb)) { + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb7, bn_glb6, bn_glb3); + } + } + BN_clear(bn_glb7); + BN_set_word(bn_glb7, 1); + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb7, bn_glb6, bn_glb3); + BN_clear(bn_glb0); + } + BN_free(var30); + BN_free(var50); +} + +//uses 3, 6, a, b, c, l, glb2pow128 +//sets 0, 1, 5, 7, a, b, c, f, g +void cN2Map57::bn_func2(int arg0) +{ + BN_copy(bn_glb1, bn_glb_b); + + mod_add(bn_glb1, bn_glb1, bn_glb1, bn_glb3); + BN_copy(bn_glb7, bn_glb1); + BN_copy(bn_glb5, bn_glb_c); + BN_mask_bits(bn_glb1, 128); + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb5, bn_glb6, bn_glb3); + BN_copy(bn_glb_g, bn_glb1); + BN_copy(bn_glb1, bn_glb7); + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb1, bn_glb6, bn_glb3); + BN_copy(bn_glb7, bn_glb_a); + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb7, bn_glb6, bn_glb3); + mod_sub(); + BN_copy(bn_glb_f, bn_glb1); + BN_copy(bn_glb1, bn_glb7); + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb1, bn_glb6, bn_glb3); + BN_copy(bn_glb7, bn_glb1); + + mod_add(bn_glb1, bn_glb1, bn_glb1, bn_glb3); + + mod_add(bn_glb1, bn_glb1, bn_glb7, bn_glb3); + BN_copy(bn_glb7, bn_glb1); + BN_copy(bn_glb1, bn_glb_c); + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb1, bn_glb6, bn_glb3); + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb1, bn_glb6, bn_glb3); + BN_copy(bn_glb5, bn_glb_l); + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb5, bn_glb6, bn_glb3); + + mod_add(bn_glb1, bn_glb1, bn_glb7, bn_glb3); + BN_copy(bn_glb7, bn_glb1); + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb1, bn_glb6, bn_glb3); + BN_copy(bn_glb0, bn_glb_f); + + mod_add(bn_glb1, bn_glb0, bn_glb1, bn_glb3); + mod_add(bn_glb1, bn_glb0, bn_glb1, bn_glb3); + if(arg0 == 0) { + BN_copy(bn_glb_a, bn_glb1); + } else { + BN_copy(bn_glb_f, bn_glb1); + } + + mod_add(bn_glb1, bn_glb0, bn_glb1, bn_glb3); + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb7, bn_glb6, bn_glb3); + BN_copy(bn_glb7, bn_glb1); + BN_copy(bn_glb1, bn_glb_b); + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb1, bn_glb6, bn_glb3); + + mod_add(bn_glb1, bn_glb1, bn_glb1, bn_glb3); + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb1, bn_glb6, bn_glb3); + + mod_add(bn_glb1, bn_glb1, bn_glb1, bn_glb3); + + mod_add(bn_glb1, bn_glb1, bn_glb7, bn_glb3); + mod_sub(); + if(arg0 == 0) { + BN_copy(bn_glb_b, bn_glb1); + BN_copy(bn_glb_c, bn_glb_g); + } else { + BN_copy(bn_glb_f, bn_glb1); + BN_copy(bn_glb_f, bn_glb_g); + } +} + +//uses 3, 6, a, b, c, d, e, k +//sets 0, 1, 5, 7, a, b, c, f, g, h, i, j +void cN2Map57::bn_func3(int arg0) +{ + BN_copy(bn_glb1, bn_glb_c); + BN_copy(bn_glb7, bn_glb1); + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb1, bn_glb6, bn_glb3); + + bn_cmplx1(bn_glb0, bn_glb1, bn_glb7, bn_glb6, bn_glb3); + BN_copy(bn_glb_f, bn_glb0); + BN_copy(bn_glb5, bn_glb_d); + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb5, bn_glb6, bn_glb3); + BN_copy(bn_glb7, bn_glb1); + mod_sub(); + BN_copy(bn_glb0, bn_glb_a); + + mod_add(bn_glb1, bn_glb0, bn_glb1, bn_glb3); + BN_copy(bn_glb_g, bn_glb1); + BN_copy(bn_glb5, bn_glb_c); + + bn_cmplx1(bn_glb0, bn_glb1, bn_glb5, bn_glb6, bn_glb3); + if(arg0 == 0) { + BN_copy(bn_glb_c, bn_glb0); + } else { + BN_copy(bn_glb_g, bn_glb0); + } + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb1, bn_glb6, bn_glb3); + BN_copy(bn_glb_h, bn_glb1); + BN_copy(bn_glb0, bn_glb_a); + + mod_add(bn_glb0, bn_glb0, bn_glb7, bn_glb3); + BN_copy(bn_glb7, bn_glb0); + + //NOTE: don't 'mod' bn_glb1, but DO 'mod' glb_i + bn_cmplx1(bn_glb7, bn_glb1, bn_glb7, bn_glb6, bn_glb3); + bn_cmplx1a(bn_glb1, bn_glb1, bn_glb7, bn_glb6, bn_glb3); + BN_copy(bn_glb_i, bn_glb7); + BN_copy(bn_glb1, bn_glb_e); + BN_copy(bn_glb5, bn_glb_f); + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb5, bn_glb6, bn_glb3); + BN_copy(bn_glb_f, bn_glb1); + mod_sub(); + BN_copy(bn_glb0, bn_glb_b); + + mod_add(bn_glb1, bn_glb0, bn_glb1, bn_glb3); + BN_copy(bn_glb_j, bn_glb1); + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb1, bn_glb6, bn_glb3); + BN_copy(bn_glb0, bn_glb1); + BN_copy(bn_glb1, bn_glb7); + BN_copy(bn_glb7, bn_glb0); + mod_sub(); + + mod_add(bn_glb1, bn_glb1, bn_glb7, bn_glb3); + if(arg0 == 0) { + BN_copy(bn_glb_a, bn_glb1); + } else { + BN_copy(bn_glb_f, bn_glb1); + } + + mod_add(bn_glb1, bn_glb1, bn_glb1, bn_glb3); + mod_sub(); + BN_copy(bn_glb7, bn_glb_i); + + mod_add(bn_glb1, bn_glb1, bn_glb7, bn_glb3); + BN_copy(bn_glb5, bn_glb_j); + + bn_cmplx1(bn_glb0, bn_glb1, bn_glb5, bn_glb6, bn_glb3); + BN_copy(bn_glb1, bn_glb_f); + BN_copy(bn_glb_f, bn_glb0); + BN_copy(bn_glb7, bn_glb_b); + + mod_add(bn_glb1, bn_glb1, bn_glb7, bn_glb3); + BN_copy(bn_glb7, bn_glb1); + BN_copy(bn_glb1, bn_glb_g); + BN_copy(bn_glb5, bn_glb_h); + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb5, bn_glb6, bn_glb3); + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb7, bn_glb6, bn_glb3); + mod_sub(); + BN_copy(bn_glb7, bn_glb_f); + + mod_add(bn_glb1, bn_glb1, bn_glb7, bn_glb3); + BN_copy(bn_glb5, bn_glb_k); + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb5, bn_glb6, bn_glb3); + if(arg0 == 0) { + BN_copy(bn_glb_b, bn_glb1); + } else { + BN_copy(bn_glb_f, bn_glb1); + } +} + +//uses c, d, e, m +//sets 0, a, b, c +void cN2Map57::bn_cmplx7() +{ + BIGNUM *var1; + var1 = BN_new(); + BN_copy(bn_glb0, bn_glb_c); + if(BN_is_zero(bn_glb_c)) { + BN_copy(bn_glb_a, bn_glb_d); + BN_copy(bn_glb_b, bn_glb_e); + BN_copy(bn_glb_c, bn_glb_m); + bn_func3(1); + } else { + BN_clear(var1); + BN_set_word(var1, 0xFFFFFFFF); + BN_mask_bits(bn_glb_a, 32); + BN_lshift(var1, bn_glb_m, 0x20); + BN_add(bn_glb_a, bn_glb_a, var1); + BN_mask_bits(bn_glb_a, 128); + bn_func3(0); + } + BN_free(var1); +} + +void cN2Map57::bn_cmplx2(BIGNUM *var1, BIGNUM *var2, BIGNUM *var3, BIGNUM *var4, BIGNUM *var5, BIGNUM *var6) +{ + BIGNUM *var48; + int len = BN_num_bits(var6); + int i; + if(len < 2) + return; + + if(BN_is_zero(var2) && BN_is_zero(var3) && BN_is_zero(var4)) + return; + var48 = BN_new(); + BN_copy(bn_glb3, var1); + + BN_copy(bn_glb6, bn_glb3); + BN_set_bit(bn_glb6, 0); + BN_sub(bn_glb6, glb2pow128, bn_glb6); + BN_mod_inverse(bn_glb6, bn_glb6, glb2pow64, t1); + BN_clear(bn_glb0); + // + if(! BN_is_zero(bn_glb3)) { + BN_clear(bn_glb1); + BN_set_word(bn_glb1, 2); + BN_clear(bn_glb_k); + BN_set_word(bn_glb_k, 0x88); + BN_mod_exp(bn_glb1, bn_glb1, bn_glb_k, bn_glb3, t1); + } + // + for(i=0; i < 4; i++) { + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb1, bn_glb6, bn_glb3); + } + // + BN_clear(bn_glb7); + BN_set_word(bn_glb7, 1); + BN_add(bn_glb0, bn_glb3, bn_glb7); + BN_copy(bn_glb_k, bn_glb0); + BN_rshift(bn_glb_k, bn_glb_k, 1); + BN_copy(bn_glb7, bn_glb1); + BN_copy(bn_glb5, bn_glb_k); + BN_mask_bits(bn_glb5, 128); + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb5, bn_glb6, bn_glb3); + BN_copy(bn_glb_k, bn_glb1); + + BN_copy(bn_glb1, var5); + BN_mask_bits(bn_glb1, 128); + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb7, bn_glb6, bn_glb3); + BN_copy(bn_glb_l, bn_glb1); + BN_copy(bn_glb1, bn_glb7); + BN_clear(bn_glb5); + BN_set_word(bn_glb5, 1); + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb5, bn_glb6, bn_glb3); + BN_copy(bn_glb_c, bn_glb1); + BN_copy(bn_glb_m, bn_glb1); + BN_copy(bn_glb1, bn_glb7); + + BN_copy(bn_glb5, var2); + BN_mask_bits(bn_glb5, 128); + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb5, bn_glb6, bn_glb3); + BN_copy(bn_glb_a, bn_glb1); + BN_copy(bn_glb1, bn_glb7); + + BN_copy(bn_glb5, var3); + BN_mask_bits(bn_glb5, 128); + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb5, bn_glb6, bn_glb3); + BN_copy(bn_glb_b, bn_glb1); + BN_copy(bn_glb_d, bn_glb_a); + BN_copy(bn_glb_e, bn_glb_b); + + int x = len -1; + while(x > 0) { + x--; + bn_func2(0); + if(BN_is_bit_set(var6, x)) { + bn_cmplx7(); + } + } + + BN_copy(bn_glb1, bn_glb_c); + BN_mask_bits(bn_glb1, 128); + BN_copy(bn_glb7, bn_glb1); + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb1, bn_glb6, bn_glb3); + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb7, bn_glb6, bn_glb3); + BN_clear(bn_glb7); + BN_set_word(bn_glb7, 1); + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb7, bn_glb6, bn_glb3); + BN_copy(bn_glb0, bn_glb1); + BN_clear(bn_glb7); + BN_set_word(bn_glb7, 1); + BN_copy(bn_glb1, bn_glb0); + BN_clear(bn_glb0); + bn_func1(var1); + BN_copy(bn_glb5, bn_glb_b); + BN_mask_bits(bn_glb5, 128); + + bn_cmplx1(bn_glb0, bn_glb1, bn_glb5, bn_glb6, bn_glb3); + + BN_copy(bn_glb7, bn_glb0); + BN_copy(bn_glb5, bn_glb_c); + BN_mask_bits(bn_glb5, 128); + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb5, bn_glb6, bn_glb3); + + BN_copy(bn_glb5, bn_glb_a); + BN_mask_bits(bn_glb5, 128); + + bn_cmplx1(bn_glb1, bn_glb1, bn_glb5, bn_glb6, bn_glb3); + + BN_clear(bn_glb5); + BN_set_word(bn_glb5, 1); + + bn_cmplx1(bn_glb0, bn_glb1, bn_glb5, bn_glb6, bn_glb3); + BN_copy(bn_glb_a, bn_glb0); + BN_copy(bn_glb1, bn_glb7); + + BN_clear(bn_glb5); + BN_set_word(bn_glb5, 1); + + bn_cmplx1(bn_glb0, bn_glb1, bn_glb5, bn_glb6, bn_glb3); + BN_copy(bn_glb_b, bn_glb0); + BN_free(var48); +} + +void cN2Map57::Map57(unsigned char *data) +{ + BIGNUM *var38, *var58, *var78, *var98, *varb8, *vard8; + BN_CTX *t; + unsigned char tmpdata[256]; + unsigned char res[256]; + + t = BN_CTX_new(); + t1 = BN_CTX_new(); + BN_CTX_init(t); + + glb2pow128 = BN_new(); + BN_clear(glb2pow128); + BN_set_bit(glb2pow128, 128); + mask128 = BN_new(); + BN_hex2bn(&mask128, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"); + + glb2pow64 = BN_new(); + BN_clear(glb2pow64); + BN_set_bit(glb2pow64, 64); + mask64 = BN_new(); + BN_hex2bn(&mask64, "FFFFFFFFFFFFFFFF"); + + bn_glb0=BN_new(); BN_clear(bn_glb0); + bn_glb1=BN_new(); BN_clear(bn_glb1); + bn_glb3=BN_new(); BN_clear(bn_glb3); + bn_glb5=BN_new(); BN_clear(bn_glb5); + bn_glb6=BN_new(); BN_clear(bn_glb6); + bn_glb7=BN_new(); BN_clear(bn_glb7); + + bn_glb_a=BN_new(); BN_clear(bn_glb_a); + bn_glb_b=BN_new(); BN_clear(bn_glb_b); + bn_glb_c=BN_new(); BN_clear(bn_glb_c); + bn_glb_d=BN_new(); BN_clear(bn_glb_d); + bn_glb_e=BN_new(); BN_clear(bn_glb_e); + bn_glb_f=BN_new(); BN_clear(bn_glb_f); + bn_glb_g=BN_new(); BN_clear(bn_glb_g); + bn_glb_h=BN_new(); BN_clear(bn_glb_h); + bn_glb_i=BN_new(); BN_clear(bn_glb_i); + bn_glb_j=BN_new(); BN_clear(bn_glb_j); + bn_glb_k=BN_new(); BN_clear(bn_glb_k); + bn_glb_l=BN_new(); BN_clear(bn_glb_l); + bn_glb_m=BN_new(); BN_clear(bn_glb_m); + + var38=BN_new(); BN_clear(var38); + var58=BN_new(); BN_clear(var58); + var78=BN_new(); BN_clear(var78); + var98=BN_new(); BN_clear(var98); + varb8=BN_new(); BN_clear(varb8); + vard8=BN_new(); BN_clear(vard8); + + memcpy(tmpdata, data, 0x60); + RotateBytes(tmpdata, 0x60); + BN_bin2bn(tmpdata, 16, var98); + BN_bin2bn(tmpdata+0x10, 16, var78); + BN_bin2bn(tmpdata+0x20, 16, var38); + BN_bin2bn(tmpdata+0x30, 16, vard8); + BN_bin2bn(tmpdata+0x40, 16, var58); + BN_bin2bn(tmpdata+0x50, 16, varb8); + + bn_cmplx2(varb8, var58, vard8, var38, var78, var98); + + memset(res, 0, 0x80); + unsigned int *dest = (unsigned int *)res, *src = (unsigned int *)data; + *dest++ = src[0x03]; + *dest++ = src[0x02]; + *dest++ = src[0x01]; + *dest++ = src[0x00]; + *dest++ = src[0x07]; + *dest++ = src[0x06]; + *dest++ = src[0x05]; + *dest++ = src[0x04]; + + memset(tmpdata, 0, 0x20); + int len = BN_bn2bin(bn_glb_a, tmpdata); + if(len) { + RotateBytes(tmpdata, len); + } + src = (unsigned int *)tmpdata; + *dest++ = src[0x03]; + *dest++ = src[0x02]; + *dest++ = src[0x01]; + *dest++ = src[0x00]; + + memset(tmpdata, 0, 0x20); + len = BN_bn2bin(bn_glb_m, tmpdata); + if(len) { + RotateBytes(tmpdata, len); + } + *dest = src[0x03]; + dest+=4; + + memset(tmpdata, 0, 0x20); + len = BN_bn2bin(bn_glb_b, tmpdata); + if(len) { + RotateBytes(tmpdata, len); + } + *dest++ = src[0x03]; + *dest++ = src[0x02]; + *dest++ = src[0x01]; + *dest++ = src[0x00]; + + dest+=4; + src = (unsigned int *)(data+0x60); + *dest++ = src[0x03]; + *dest++ = src[0x02]; + *dest++ = src[0x01]; + *dest++ = src[0x00]; + *dest++ = src[0x07]; + *dest++ = src[0x06]; + *dest++ = src[0x05]; + *dest++ = src[0x04]; + + *(unsigned int *)(data + (0<<2))= *(unsigned int *)(res + (11<<2)); + *(unsigned int *)(data + (1<<2))= *(unsigned int *)(res + (10<<2)); + *(unsigned int *)(data + (2<<2))= *(unsigned int *)(res + (9<<2)); + *(unsigned int *)(data + (3<<2))= *(unsigned int *)(res + (8<<2)); + *(unsigned int *)(data + (4<<2))= *(unsigned int *)(res + (12<<2)); + *(unsigned int *)(data + (5<<2))= *(unsigned int *)(res + (13<<2)); + *(unsigned int *)(data + (6<<2))= *(unsigned int *)(res + (14<<2)); + *(unsigned int *)(data + (7<<2))= *(unsigned int *)(res + (15<<2)); + *(unsigned int *)(data + (8<<2))= *(unsigned int *)(res + (19<<2)); + *(unsigned int *)(data + (9<<2))= *(unsigned int *)(res + (18<<2)); + *(unsigned int *)(data + (10<<2))= *(unsigned int *)(res + (17<<2)); + *(unsigned int *)(data + (11<<2))= *(unsigned int *)(res + (16<<2)); + *(unsigned int *)(data + (12<<2))= *(unsigned int *)(res + (20<<2)); + *(unsigned int *)(data + (13<<2))= *(unsigned int *)(res + (21<<2)); + *(unsigned int *)(data + (14<<2))= *(unsigned int *)(res + (22<<2)); + *(unsigned int *)(data + (15<<2))= *(unsigned int *)(res + (23<<2)); + + BN_free(glb2pow128); + BN_free(mask128); + BN_free(glb2pow64); + BN_free(mask64); + + BN_free(bn_glb0); + BN_free(bn_glb1); + BN_free(bn_glb3); + BN_free(bn_glb5); + BN_free(bn_glb6); + BN_free(bn_glb7); + + BN_free(bn_glb_a); + BN_free(bn_glb_b); + BN_free(bn_glb_c); + BN_free(bn_glb_d); + BN_free(bn_glb_e); + BN_free(bn_glb_f); + BN_free(bn_glb_g); + BN_free(bn_glb_h); + BN_free(bn_glb_i); + BN_free(bn_glb_j); + BN_free(bn_glb_k); + BN_free(bn_glb_l); + BN_free(bn_glb_m); + + BN_free(var38); + BN_free(var58); + BN_free(var78); + BN_free(var98); + BN_free(varb8); + BN_free(vard8); + + BN_CTX_free(t); + BN_CTX_free(t1); +} diff -ruN sc-0.8.7/testing/compat.h sc-src/testing/compat.h --- sc-0.8.7/testing/compat.h 2008-01-03 09:40:47.000000000 -0500 +++ sc-src/testing/compat.h 2008-02-06 16:49:45.000000000 -0500 @@ -4,3 +4,4 @@ void LogAll(void); void SDump(const unsigned char *buffer, int n); int ReadRaw(const char *name, unsigned char *buff, int maxlen); +pthread_attr_t default_attr; diff -ruN sc-0.8.7/testing/testN2RunEmu.c sc-src/testing/testN2RunEmu.c --- sc-0.8.7/testing/testN2RunEmu.c 2008-01-03 09:40:47.000000000 -0500 +++ sc-src/testing/testN2RunEmu.c 2008-02-06 16:49:45.000000000 -0500 @@ -19,7 +19,7 @@ InitAll(argv[1]); LogAll(); cLogging::SetModuleOption(LCLASS(L_SYS,L_SYS_DISASM),false); - unsigned char data[1024]; + unsigned char data[2048]; unsigned int len = 0; char *p = argv[3]; char last = -1; @@ -44,6 +44,6 @@ int id=strtol(argv[2],0,0); cN2Prov *emmP=cN2Providers::GetProv(id,N2FLAG_NONE); HEXDUMP(0, data, len, "Input"); - if(emmP->RunEmu(data, len, 0x90, 0x90, 0x00, 0x00, 0x300)>=0) - HEXDUMP(0, data, 0x300, "Output"); + if(emmP->RunEmu(data, len, 0x90, 0x90, 0x00, 0x00, 0x440)>=0) + HEXDUMP(0, data, 0x440, "Output"); }