SASC-NG
DVBSoftCAM

fake-nds.c

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 #include <stdlib.h>
00021 #include <string.h>
00022 
00023 #include <openssl/md5.h>
00024 
00025 #include "system-common.h"
00026 #include "data.h"
00027 #include "helper.h"
00028 
00029 #include "nds.h"
00030 #include "log-nds.h"
00031 
00032 #define SYSTEM_NAME          "Fake-NDS"
00033 #define SYSTEM_PRI           -12
00034 
00035 // -- cSystemFakeNDS -----------------------------------------------------------
00036 
00037 class cSystemFakeNDS : public cSystem {
00038 private:
00039   cFileMap *fm;
00040   bool mapMD5ok;
00041   //
00042   bool MapFlash(const char *name, int len, const unsigned char *appmd);
00043 public:
00044   cSystemFakeNDS(void);
00045   ~cSystemFakeNDS();
00046   virtual bool ProcessECM(const cEcmInfo *ecm, unsigned char *data);
00047   };
00048 
00049 cSystemFakeNDS::cSystemFakeNDS(void)
00050 :cSystem(SYSTEM_NAME,SYSTEM_PRI)
00051 {
00052   fm=0; mapMD5ok=false;
00053   memset(cw,0,sizeof(cw));
00054 }
00055 
00056 cSystemFakeNDS::~cSystemFakeNDS()
00057 {
00058   if(fm) fm->Unmap();
00059 }
00060 
00061 bool cSystemFakeNDS::MapFlash(const char *name, int len, const unsigned char *appmd)
00062 {
00063   if(fm && !fm->IsFileMap(name,false)) { fm->Unmap(); fm=0; }
00064   if(!fm) fm=filemaps.GetFileMap(name,FILEMAP_DOMAIN,false);
00065   if(!fm) return false;
00066   if(!fm->Addr()) {
00067     if(!fm->Map()) return false;
00068     unsigned char md[16];
00069     MD5(fm->Addr(),fm->Size(),md);
00070     if(fm->Size()<len || memcmp(md,appmd,16)) {
00071       mapMD5ok=false;
00072       if(doLog) PRINTF(L_SYS_ECM,"MD5 checksum failed on flash bin");
00073       return false;
00074       }
00075     mapMD5ok=true;
00076     }
00077   return mapMD5ok;
00078 }
00079 
00080 bool cSystemFakeNDS::ProcessECM(const cEcmInfo *ecm, unsigned char *data)
00081 {
00082   int len=SCT_LEN(data);
00083   if(len<7 || data[3]!=0x00 || data[4]!=0x00 || data[5]!=0x01) {
00084     if(doLog) PRINTF(L_SYS_ECM,"ECM format check failed");
00085     return false;
00086     }
00087   int iLen=data[6];
00088   if(iLen+6>len || iLen<0x1C) {
00089     if(doLog) PRINTF(L_SYS_ECM,"IRD block length check failed");
00090     return false;
00091     }
00092 
00093   int block1, block2, block3, block4, cwoff;
00094   if(iLen==0x1C && data[6+11]==0x0F && data[6+12]==0x40) { // PW
00095     // check cw in IRD block
00096     if(!(data[6+9]&1) || !(data[6+10]&16)) {
00097       if(doLog) PRINTF(L_SYS_ECM,"no CW in IRD block");
00098       return false;
00099       }
00100     static const unsigned char app10039[] = { 0xff,0x25,0x38,0x51,0xec,0xcb,0xc8,0xfa,0xab,0x97,0x59,0x15,0x4d,0x14,0x05,0xfa };
00101     if(!MapFlash("PR-HD1000_060000.bin",0x2603c0,app10039)) return false;
00102     block1=1;
00103     block2=23;
00104     block3=0x22D344;
00105     block4=0x25c620;
00106     cwoff=14;
00107     }
00108   else if(iLen==0x21 && data[6+14]==0x0F && data[6+15]==0x40) { // VIASAT
00109     static const unsigned char apppace[] = { 0x23,0x21,0xc3,0xe0,0xc1,0xce,0xed,0xb4,0x4b,0xd6,0xa4,0xc7,0x44,0x61,0xda,0x0e };
00110     if(!MapFlash("VIA-Pace4_060000.bin",0x2BA600,apppace)) return false;
00111     block1=1;
00112     block2=26;
00113     block3=0x28cb08;
00114     block4=0x2b5318;
00115     cwoff=17;
00116     }
00117   else {
00118     if(doLog) PRINTF(L_SYS_ECM,"failed to detect provider");
00119     return false;
00120     }
00121 
00122   unsigned char hash[94], md[16];
00123   memcpy(&hash[0],&data[6+block1],10);
00124   memcpy(&hash[10],&data[6+block2],4);
00125   memcpy(&hash[14],fm->Addr()+block3,64);
00126   memcpy(&hash[78],fm->Addr()+block4,16);
00127   MD5(hash,94,md);
00128   xxor(cw+((data[0]&1)<<3),8,&data[6+cwoff],&md[8]);
00129   return true;
00130 }
00131 
00132 // -- cSystemLinkFakeNDS -------------------------------------------------------
00133 
00134 class cSystemLinkFakeNDS : public cSystemLink {
00135 public:
00136   cSystemLinkFakeNDS(void);
00137   virtual bool CanHandle(unsigned short SysId);
00138   virtual cSystem *Create(void) { return new cSystemFakeNDS; }
00139   };
00140 
00141 static cSystemLinkFakeNDS staticInit;
00142 
00143 cSystemLinkFakeNDS::cSystemLinkFakeNDS(void)
00144 :cSystemLink(SYSTEM_NAME,SYSTEM_PRI)
00145 {}
00146 
00147 bool cSystemLinkFakeNDS::CanHandle(unsigned short SysId)
00148 {
00149   return (SysId&SYSTEM_MASK)==SYSTEM_NDS;
00150 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines