|
SASC
DVBSoftCAM
|
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