|
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 #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 }