From: leslie Date: Sun, 8 Jun 2008 13:35:35 +0000 (+0800) Subject: nagra: map register framework X-Git-Tag: 0.9.1~87 X-Git-Url: http://www.vanbest.org/gitweb/?a=commitdiff_plain;h=455f667a546605f375a7b37f9191004c7aeaa712;p=sasc-ng.git nagra: map register framework --- diff --git a/crypto-bn.h b/crypto-bn.h index 0168d94..bf9bd62 100644 --- a/crypto-bn.h +++ b/crypto-bn.h @@ -37,6 +37,7 @@ public: ~cBN() { BN_free(&big); } operator BIGNUM* () { return &big; } BIGNUM *operator->() { return &big; } + BIGNUM *BN(void) { return &big; } bool Get(const unsigned char *in, int n); bool GetLE(const unsigned char *in, int n); int Put(unsigned char *out, int n) const; diff --git a/systems/nagra/nagra2-0101.c b/systems/nagra/nagra2-0101.c index f131e63..2b92790 100644 --- a/systems/nagra/nagra2-0101.c +++ b/systems/nagra/nagra2-0101.c @@ -430,16 +430,17 @@ void cMap0101::DoMap(int f, unsigned char *data, int l) PRINTF(L_SYS_MAP,"0101: calling function %02X",f); l=GetOpSize(l); cycles=0; interrupted=false; +#ifdef MR_DEBUG +fprintf(stderr,"map %x l=%d\n",f,l); +#endif switch(f) { case 0x21: MAP_IRQ_BEGIN(); AddMapCycles(288); - WS_START(1); MakeJ0(J,D); AddMapCycles(282); - WClear(C); + WClear(C,1); AddMapCycles(898-282-288); - WS_END(); MAP_IRQ_END(); break; case 0x22: @@ -603,6 +604,7 @@ void cMap0101::DoMap(int f, unsigned char *data, int l) PRINTF(L_SYS_MAP,"0101: unsupported call %02x",f); break; } + Finalise(); } // -- cN2Prov0101 -------------------------------------------------------------- diff --git a/systems/nagra/nagra2.c b/systems/nagra/nagra2.c index 6e4ca8b..baf7c98 100644 --- a/systems/nagra/nagra2.c +++ b/systems/nagra/nagra2.c @@ -258,13 +258,71 @@ bool cN2Emu::Init(int id, int romv) return initDone; } +// -- cMapReg ------------------------------------------------------------------ + +cMapReg::cMapReg(const int *Ws) +{ + ws=Ws; +} + +void cMapReg::Save(int size) +{ + if(!touched && ws) { + if(size<=0) size=*ws; + BN_copy(save,reg); + BN_mask_bits(reg,size<<6); + touched=true; +#ifdef MR_DEBUG +fprintf(stderr,"saved %p size=%d\n",this,size); +BN_print_fp(stderr,reg); fprintf(stderr,"\n"); +BN_print_fp(stderr,save); fprintf(stderr,"\n"); +#endif + } +} + +void cMapReg::Restore(int size) +{ + if(touched && ws) { + if(size<=0) size=*ws; +#ifdef MR_DEBUG +fprintf(stderr,"restore %p size=%d\n",this,size); +BN_print_fp(stderr,reg); fprintf(stderr,"\n"); +BN_print_fp(stderr,save); fprintf(stderr,"\n"); +#endif + if(reg->neg) { + BN_zero(tmp); + BN_set_bit(tmp,size<<6); + BN_add(reg,tmp,reg); + } + BN_rshift(tmp,save,size<<6); + BN_lshift(tmp,tmp,size<<6); + BN_mask_bits(reg,size<<6); + BN_add(reg,reg,tmp); + touched=false; +#ifdef MR_DEBUG +BN_print_fp(stderr,reg); fprintf(stderr,"\n"); +#endif + } +} + // -- cMapMath ----------------------------------------------------------------- +const int cMapMath::ws1=1; + cMapMath::cMapMath(void) +:A(&wordsize),B(&wordsize),C(&wordsize),D(&wordsize),J(&ws1),I(0) { wordsize=DEF_WORDSIZE; } +void cMapMath::Finalise(void) +{ +#ifdef MR_DEBUG +fprintf(stderr,"finalise\n"); +#endif + A.Restore(); B.Restore(); C.Restore(); D.Restore(); +} + void cMapMath::WClear(BIGNUM *r, int w) { if(!w) w=wordsize; @@ -551,6 +609,7 @@ bool cMapCore::DoMap(int f, unsigned char *data, int l) cycles=890-6; last=0; regs[0]->GetLE(data,8); + regs[0]->Restore(1); break; case IMPORT_A: case IMPORT_B: @@ -561,12 +620,14 @@ bool cMapCore::DoMap(int f, unsigned char *data, int l) cycles+=771+160*l-6; last=f-IMPORT_J; regs[last]->GetLE(data,l<<3); + regs[last]->Restore(l); break; case IMPORT_LAST: if(l>16) { l=1; cycles+=5; } else if(l<=0) l=1; cycles=656+160*l-6; regs[last]->GetLE(data,(last==0?1:l)<<3); + regs[last]->Restore((last==0?1:l)); break; case EXPORT_J: @@ -646,6 +707,7 @@ bool cMapCore::DoMap(int f, unsigned char *data, int l) default: return false; } + Finalise(); return true; } diff --git a/systems/nagra/nagra2.h b/systems/nagra/nagra2.h index 30cf002..0e68e8a 100644 --- a/systems/nagra/nagra2.h +++ b/systems/nagra/nagra2.h @@ -50,6 +50,27 @@ extern char auxPassword[250]; // ---------------------------------------------------------------- +//#define MR_DEBUG + +class cMapReg { +private: + cBN reg, save, tmp; + const int *ws; + bool touched; +public: + cMapReg(const int *Ws); + operator BIGNUM* () { Save(); return reg.BN(); } + BIGNUM *operator->() { Save(); return reg.BN(); } + bool Get(const unsigned char *in, int n) { Save(); return reg.Get(in,n); } + bool GetLE(const unsigned char *in, int n) { Save(); return reg.GetLE(in,n); } + int Put(unsigned char *out, int n) const { return reg.Put(out,n); } + int PutLE(unsigned char *out, int n) const { return reg.PutLE(out,n); } + void Save(int size=0); + void Restore(int size=0); + }; + +// ---------------------------------------------------------------- + #define DEF_WORDSIZE 4 #define WS_START(x) { int __oldws=wordsize; wordsize=(x); @@ -59,9 +80,10 @@ class cMapMath { private: cBN x, y, s; int words; + static const int ws1; protected: int wordsize; - cBN A, B, C, D, J, I; + cMapReg A, B, C, D, J, I; cBNctx ctx; SHA_CTX sctx; // stateless @@ -75,6 +97,7 @@ protected: // statefull void MonMul(BIGNUM *o, BIGNUM *a, BIGNUM *b); void MonMul(BIGNUM *o, BIGNUM *a, BIGNUM *b, int w); + void Finalise(void); public: cMapMath(void); }; @@ -113,7 +136,7 @@ class cMapCore : public cMapMath { private: int last; cBN e; - cBN *regs[5]; + cMapReg *regs[5]; protected: unsigned int cycles; cBN Px, Py, Pz,Qx, Qy, Qz; // 0x00,0x20,0x40,0x60,0x80,0x180