SASC
DVBSoftCAM

nagra2.h

Go to the documentation of this file.
00001 /*
00002  * Softcam plugin to VDR (C++)
00003  *
00004  * This code is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This code is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
00018  */
00019 
00020 #ifndef __NAGRA_NAGRA2_H
00021 #define __NAGRA_NAGRA2_H
00022 
00023 #include "data.h"
00024 #include "crypto.h"
00025 #include "misc.h"
00026 #include "helper.h"
00027 
00028 #include <openssl/des.h>
00029 #include <openssl/sha.h>
00030 #include "openssl-compat.h"
00031 
00032 #include "nagra-def.h"
00033 #include "cpu.h"
00034 #include "log-nagra.h"
00035 
00036 // ----------------------------------------------------------------
00037 
00038 #define MATCH_ID(x,y) ((((x)^(y))&~0x107)==0)
00039 
00040 // ----------------------------------------------------------------
00041 
00042 #define HAS_AUXSRV
00043 
00044 #ifdef HAS_AUXSRV
00045 extern int auxEnabled;
00046 extern int auxPort;
00047 extern char auxAddr[80];
00048 extern char auxPassword[250];
00049 #endif
00050 
00051 // ----------------------------------------------------------------
00052 
00053 #define DEF_WORDSIZE 4
00054 #define DEF_MAXWORDSIZE 17
00055 
00056 class cMapReg {
00057 private:
00058   cBN fullreg, reg, tmp;
00059   int wordsize, maxwordsize, *defwordsize, &pos;
00060   //
00061   int DefWordSize() const { return defwordsize ? *defwordsize:DEF_WORDSIZE; }
00062   int OpWordSize(int wsize) const { int sz=wsize>0 ? wsize:DefWordSize(); return sz>maxwordsize ? maxwordsize:sz; }
00063 //  int OpWordSize() const { return wordsize; }
00064   void ClearReg(int wsize);
00065   void ClearFullReg(int wsize);
00066   void PrepTmp(BIGNUM *val, int wsize);
00067 protected:
00068   void SetMaxWordSize(int max) { maxwordsize=max; }
00069   void SetDefWordSize(int *_defwordsize) { defwordsize=_defwordsize; }
00070 public:
00071   cMapReg(int &_pos, int *_defwordsize=0, int _maxwordsize=DEF_MAXWORDSIZE);
00072   operator BIGNUM* () { return Value(); }
00073   BIGNUM *operator->() { return Value(); }
00074   BIGNUM *Value(int wsize=0, bool mask=false);
00075   void Commit(int wsize=-1, int resync=-1);
00076   void Reload(int wsize=0);
00077   void GetLE(const unsigned char *in, int n=0);
00078   void PutLE(unsigned char *out, int n=0);
00079   void Set(BIGNUM *val, int wsize);
00080   void Clear(int wsize);
00081   void SetPos(int _pos) { pos=_pos; }
00082   };
00083 
00084 // ----------------------------------------------------------------
00085 
00086 #define WS_START(x) { int __oldws=wordsize; wordsize=(x);
00087 #define WS_END()    wordsize=__oldws; }
00088 
00089 class cMapMath {
00090 private:
00091   cBN x, y, s;
00092   int words;
00093 protected:
00094   int wordsize, regpos;
00095   cMapReg A, B, C, D, J, I;
00096   cBN H, scalar;
00097   cBNctx ctx;
00098   SHA_CTX sctx;
00099   // stateless
00100   void MakeJ0(BIGNUM *j, BIGNUM *d, BIGNUM *c=0, int bits=64);
00101   bool ModAdd(BIGNUM *r, BIGNUM *a, BIGNUM *b, BIGNUM *d);
00102   bool ModSub(BIGNUM *r, BIGNUM *d, BIGNUM *b);
00103   void MonMul(BIGNUM *o, BIGNUM *a, BIGNUM *b, BIGNUM *c, BIGNUM *d, BIGNUM *j, int w);
00104   void MonMul0(BIGNUM *o, BIGNUM *a, BIGNUM *b, BIGNUM *c, BIGNUM *d, BIGNUM *j, int w);
00105   void MonStart(int w);
00106   void MonLoop(BIGNUM *o, BIGNUM *a, BIGNUM *b, BIGNUM *c, BIGNUM *d, BIGNUM *j);
00107   void MonFin(BIGNUM *s, BIGNUM *d);
00108   // statefull
00109   void MonMul(BIGNUM *o, BIGNUM *a, BIGNUM *b);
00110   void MonMul(BIGNUM *o, BIGNUM *a, BIGNUM *b, int w);
00111 public:
00112   cMapMath(void);
00113   };
00114 
00115 // ----------------------------------------------------------------
00116 
00117 #define SETSIZE     0x02
00118 #define IMPORT_J    0x03
00119 #define IMPORT_A    0x04
00120 #define IMPORT_B    0x05
00121 #define IMPORT_C    0x06
00122 #define IMPORT_D    0x07
00123 #define IMPORT_LAST 0x08
00124 #define EXPORT_J    0x09
00125 #define EXPORT_A    0x0A
00126 #define EXPORT_B    0x0B
00127 #define EXPORT_C    0x0C
00128 #define EXPORT_D    0x0D
00129 #define EXPORT_LAST 0x0E
00130 #define SWAP_A      0x0F
00131 #define SWAP_B      0x10
00132 #define SWAP_C      0x11
00133 #define SWAP_D      0x12
00134 #define CLEAR_A     0x13
00135 #define CLEAR_B     0x14
00136 #define CLEAR_C     0x15
00137 #define CLEAR_D     0x16
00138 #define COPY_A_B    0x17
00139 #define COPY_B_A    0x18
00140 #define COPY_A_C    0x19
00141 #define COPY_C_A    0x1A
00142 #define COPY_C_D    0x1B
00143 #define COPY_D_C    0x1C
00144 
00145 class cMapCore : public cMapMath {
00146 private:
00147   int mapid, last;
00148   cBN e;
00149   cMapReg *regs[5];
00150   bool interruptible, interrupted;
00151   //
00152   bool MapGeneric(int f, unsigned char *data, int l);
00153 protected:
00154   unsigned int cycles;
00155   cBN Px, Py, Pz,Qx, Qy, Qz; // 0x00,0x20,0x40,0x60,0x80,0x180
00156   cBN sA0, sC0, sE0, s100, s120, s140, s160;
00157   // statefull
00158   void MonInit(int bits=0);
00159   void MonExp(BIGNUM *scalar);
00160   void MonExpNeg(void);
00161   // statefull, interruptible
00162   void IMakeJ(void);
00163   void IMonInit0(int bits=0);
00164   void IMonInit(int bits=0);
00165   // ECC
00166   void DoubleP(int temp);
00167   void AddP(int temp);
00168   void ToProjective(int set, BIGNUM *x, BIGNUM *y);
00169   void ToAffine(void);
00170   void CurveInit(BIGNUM *a);
00171   //
00172   int GetOpSize(int l);
00173   void DoMap(int f, unsigned char *data=0, int l=0);
00174   virtual bool Map(int f, unsigned char *data, int l) { return false; }
00175   void SetMapIdent(int Mapid) { mapid=Mapid; }
00176   bool Interruptible(void) { return interruptible; }
00177   bool Interrupted(void) { return interrupted; }
00178   virtual void AddMapCycles(unsigned int num) {}
00179   unsigned int MapCycles(void) { return cycles; }
00180   virtual unsigned int CpuCycles(void) { return 0; }
00181   virtual void PostDecryptSetup(bool ecm);
00182 public:
00183   cMapCore(void);
00184   virtual ~cMapCore() {}
00185   };
00186 
00187 // ----------------------------------------------------------------
00188 
00189 class cN2Timer {
00190 private:
00191   int ctrl, latch, nr, delayInterrupt;
00192   unsigned char val;
00193   unsigned int cycles, intrCycles;
00194   double divisor, invDivisor;
00195   bool timerBugged;
00196   enum { tmCONTINUOUS=0x01, tmRUNNING=0x02, tmINTERRUPT=0x04, tmMASK=0xFF, tmLATCHED=0x100 };
00197   //
00198   bool Running(void) { return ctrl&tmRUNNING; }
00199   bool InterruptSet(void) { return ctrl&tmINTERRUPT; }
00200   void Stop(void);
00201   double GetDivisor(void);
00202   void Update(void);
00203 public:
00204   cN2Timer(void);
00205   bool AddCycles(unsigned int count);
00206   unsigned int Cycles(void);
00207   unsigned char Ctrl(void);
00208   void Ctrl(unsigned char c);
00209   unsigned char Latch(void) { return latch&0xFF; }
00210   void Latch(unsigned char val);
00211   void SetNumber(int Nr) { nr=Nr; }
00212   int Number(void) { return nr; }
00213   };
00214 
00215 // ----------------------------------------------------------------
00216 
00217 class cN2CRC {
00218 private:
00219   enum { CRCCALC_DELAY=8, CRC_BUSY=1, CRC_DISABLED=2 };
00220   unsigned short CRCvalue;
00221   unsigned char ctrl, CRCpos, CRCin;
00222   unsigned int cycles, CRCtime, CRCit;
00223   unsigned short table[256];
00224   //
00225   void GenTable(void);
00226   void Update(void);
00227 public:
00228   cN2CRC(void);
00229   void AddCycles(unsigned int num);
00230   unsigned char Ctrl(void);
00231   void Ctrl(unsigned char c);
00232   unsigned char Data(void);
00233   void Data(unsigned char d);
00234   };
00235 
00236 // ----------------------------------------------------------------
00237 
00238 #define HW_REGS   0x20
00239 #define HW_OFFSET 0x0000
00240 
00241 #define MAX_TIMERS 3
00242 #define TIMER_NUM(x) (((x)>>2)&3) // timer order doesn't match HW order
00243 #define HW_NUM(x)    ((x+1)%3)
00244 
00245 class cMapMemHW : public cMapMem {
00246 private:
00247   // memory mapped HW
00248   enum {
00249     HW_IO=0x00, HW_SECURITY,
00250     HW_TIMER0_DATA=0x08, HW_TIMER0_LATCH, HW_TIMER0_CONTROL,
00251     HW_CRC_CONTROL=0x0e, HW_CRC_DATA,
00252     HW_TIMER1_DATA=0x10, HW_TIMER1_LATCH, HW_TIMER1_CONTROL,
00253     HW_TIMER2_DATA=0x14, HW_TIMER2_LATCH, HW_TIMER2_CONTROL
00254     };
00255   // timer hardware
00256   cN2Timer timer[MAX_TIMERS];
00257   // CRC hardware
00258   cN2CRC crc;
00259 public:
00260   cMapMemHW(void);
00261   virtual unsigned char Get(unsigned short ea);
00262   virtual void Set(unsigned short ea, unsigned char val);
00263   int AddCycles(unsigned int num);
00264   };
00265 
00266 // ----------------------------------------------------------------
00267 
00268 class cN2Emu : protected c6805 {
00269 private:
00270   bool initDone;
00271 protected:
00272   bool Init(int id, int romv);
00273   virtual bool RomInit(void) { return true; }
00274   virtual void Stepper(void) {}
00275 public:
00276   cN2Emu(void);
00277   virtual ~cN2Emu() {}
00278   };
00279 
00280 // ----------------------------------------------------------------
00281 
00282 #define N2FLAG_NONE     0
00283 #define N2FLAG_MECM     1
00284 #define N2FLAG_Bx       2
00285 #define N2FLAG_POSTAU   4
00286 #define N2FLAG_Ex       8
00287 #define N2FLAG_INV      128
00288 
00289 class cN2Prov {
00290 private:
00291   unsigned char seed[32], cwkey[8];
00292   bool keyValid;
00293 protected:
00294   int id, flags, seedSize;
00295   cIDEA idea;
00296   //
00297   virtual bool Algo(int algo, const unsigned char *hd, unsigned char *hw) { return false; }
00298   virtual void DynamicHD(unsigned char *hd, const unsigned char *ed) {}
00299   virtual bool NeedsCwSwap(void) { return false; }
00300   void ExpandInput(unsigned char *hw);
00301 public:
00302   cN2Prov(int Id, int Flags);
00303   virtual ~cN2Prov() {}
00304   bool MECM(unsigned char in15, int algo, const unsigned char *ed, unsigned char *cw);
00305   void SwapCW(unsigned char *cw);
00306   virtual int ProcessBx(unsigned char *data, int len, int pos) { return -1; }
00307   virtual int ProcessEx(unsigned char *data, int len, int pos) { return -1; }
00308   virtual bool PostProcAU(int id, unsigned char *data) { return true; }
00309   virtual int RunEmu(unsigned char *data, int len, unsigned short load, unsigned short run, unsigned short stop, unsigned short fetch, int fetch_len) { return -1; }
00310   virtual void PostDecrypt(bool ecm) {}
00311   bool CanHandle(int Id) { return MATCH_ID(Id,id); }
00312   bool HasFlags(int Flags) { return (flags&Flags)==Flags; }
00313   void PrintCaps(int c);
00314   };
00315 
00316 // ----------------------------------------------------------------
00317 
00318 class cN2Providers;
00319 
00320 class cN2ProvLink {
00321 friend class cN2Providers;
00322 private:
00323   cN2ProvLink *next;
00324 protected:
00325   int id, flags;
00326   //
00327   virtual cN2Prov *Create(void)=0;
00328   bool CanHandle(int Id) { return MATCH_ID(Id,id); }
00329   bool HasFlags(int Flags) { return (flags&Flags)==Flags; }
00330 public:
00331   cN2ProvLink(int Id, int Flags);
00332   virtual ~cN2ProvLink() {}
00333   };
00334 
00335 template<class PROV, int ID, int FLAGS> class cN2ProvLinkReg : public cN2ProvLink {
00336 public:
00337   cN2ProvLinkReg(void):cN2ProvLink(ID,FLAGS) {}
00338   virtual cN2Prov *Create(void) { return new PROV(id,flags); }
00339   };
00340 
00341 // ----------------------------------------------------------------
00342 
00343 class cN2Providers {
00344 friend class cN2ProvLink;
00345 private:
00346   static cN2ProvLink *first;
00347   //
00348   static void Register(cN2ProvLink *plink);
00349 public:
00350   static cN2Prov *GetProv(int Id, int Flags);
00351   };
00352 
00353 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines