|
SASC-NG
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 <stdio.h> 00021 #include <stdlib.h> 00022 #include <string.h> 00023 00024 #include "nagra2.h" 00025 00026 // -- cMap4101 ----------------------------------------------------------------- 00027 00028 class cMap4101 : public cMapCore { 00029 protected: 00030 virtual bool Map(int f, unsigned char *data, int l); 00031 }; 00032 00033 bool cMap4101::Map(int f, unsigned char *data, int l) 00034 { 00035 switch(f) { 00036 case 0x58: 00037 { 00038 cBN a, b, x, y, scalar; 00039 D.GetLE(data+0x00,16); 00040 x.GetLE(data+0x10,16); 00041 y.GetLE(data+0x20,16); 00042 b.GetLE(data+0x30,16); 00043 a.GetLE(data+0x40,16); 00044 scalar.GetLE(data+0x50,16); 00045 int scalarbits=BN_num_bits(scalar); 00046 if(scalarbits>=2 && !BN_is_zero(x) && !BN_is_zero(y) && !BN_is_zero(b)) { 00047 CurveInit(a); 00048 ToProjective(0,x,y); 00049 BN_copy(Qx,Px); 00050 BN_copy(Qy,Py); 00051 for(int i=scalarbits-2; i>=0; i--) { 00052 DoubleP(0); 00053 if(BN_is_bit_set(scalar,i)) AddP(0); 00054 } 00055 ToAffine(); 00056 } 00057 memset(data,0,64); 00058 Px.PutLE(&data[0],16); 00059 Py.PutLE(&data[32],16); 00060 break; 00061 } 00062 case 0x44: 00063 sctx.h4=UINT32_LE(data); 00064 sctx.h3=UINT32_LE(data+4); 00065 sctx.h2=UINT32_LE(data+8); 00066 sctx.h1=UINT32_LE(data+12); 00067 sctx.h0=UINT32_LE(data+16); 00068 cMapCore::DoMap(0x44,data); 00069 break; 00070 default: 00071 return false; 00072 } 00073 return true; 00074 } 00075 00076 // -- cN2Prov4101 ---------------------------------------------------------------- 00077 00078 class cN2Prov4101 : public cN2Prov, public cMap4101, public cN2Emu { 00079 protected: 00080 virtual void WriteHandler(unsigned char seg, unsigned short ea, unsigned char &op); 00081 public: 00082 cN2Prov4101(int Id, int Flags); 00083 virtual bool PostProcAU(int id, unsigned char *data); 00084 virtual int ProcessBx(unsigned char *data, int len, int pos); 00085 }; 00086 00087 static cN2ProvLinkReg<cN2Prov4101,0x4101,(N2FLAG_POSTAU|N2FLAG_Bx)> staticPL4101; 00088 00089 cN2Prov4101::cN2Prov4101(int Id, int Flags) 00090 :cN2Prov(Id,Flags) 00091 { 00092 hasWriteHandler=true; 00093 SetMapIdent(Id); 00094 } 00095 00096 bool cN2Prov4101::PostProcAU(int id, unsigned char *data) 00097 { 00098 if(data[1]==0x01) { 00099 cPlainKey *pk; 00100 if(!(pk=keys.FindKeyNoTrig('N',id,MBC(N2_MAGIC,0x30),16))) { 00101 PRINTF(L_SYS_EMM,"missing %04x NN 30 3DES key (16 bytes)",id); 00102 return false; 00103 } 00104 unsigned char dkey[16]; 00105 pk->Get(dkey); 00106 DES_key_schedule ks1, ks2; 00107 DES_key_sched((DES_cblock *)&dkey[0],&ks1); 00108 DES_key_sched((DES_cblock *)&dkey[8],&ks2); 00109 DES_ecb2_encrypt(DES_CAST(&data[7]),DES_CAST(&data[7]),&ks1,&ks2,DES_DECRYPT); 00110 DES_ecb2_encrypt(DES_CAST(&data[7+8]),DES_CAST(&data[7+8]),&ks1,&ks2,DES_DECRYPT); 00111 } 00112 return true; 00113 } 00114 00115 int cN2Prov4101::ProcessBx(unsigned char *data, int len, int pos) 00116 { 00117 if(Init(id,110)) { 00118 SetMem(0x80,data,len); 00119 SetPc(0x80+pos); 00120 SetSp(0x0FFF,0x0FE0); 00121 ClearBreakpoints(); 00122 AddBreakpoint(0xACDD); 00123 AddBreakpoint(0x9BDD); 00124 AddBreakpoint(0x7EC5); 00125 while(!Run(5000)) { 00126 switch(GetPc()) { 00127 case 0xACDD: 00128 return -1; 00129 case 0x9BDD: 00130 GetMem(0x80,data,len); 00131 return a; 00132 case 0x7EC5: 00133 { 00134 PopPc(); 00135 unsigned short args=GetPc(); 00136 int clen=Get(args+4); 00137 unsigned short ptr=(Get(args)<<8)+Get(args+1); 00138 if(clen+pos-1>len) return -1; // sanity 00139 GetMem(ptr,&data[pos-1],clen); 00140 ptr=(Get(args+2)<<8)+Get(args+3)-0x0CED+0x00B4-0x0080; // wild hack 00141 if(ptr<7 || ptr+8>len || data[ptr-1]!=0x10 || data[ptr-7]!=0x42) // sanity 00142 return -1; 00143 unsigned char tmp[96]; 00144 memcpy(&tmp[0],&data[ptr],8); 00145 ptr=(((data[ptr]&0x3F)|0x40)<<8)+(data[ptr+1]&0x7F); 00146 GetMem(ptr,&tmp[8],sizeof(tmp)-8); 00147 DoMap(0x02,0,2); 00148 DoMap(0x58,tmp); 00149 DoMap(0x43); 00150 DoMap(0x44,tmp); 00151 SetMem(0x0440,tmp,20); 00152 SetMem(0x80,data,len); 00153 SetPc(0x80+pos); 00154 break; 00155 } 00156 } 00157 } 00158 } 00159 return -1; 00160 } 00161 00162 void cN2Prov4101::WriteHandler(unsigned char seg, unsigned short ea, unsigned char &op) 00163 { 00164 if(cr==0x00) { 00165 if(ea==0x0a || ea==0x12 || ea==0x16) { 00166 unsigned char old=Get(ea); 00167 if(old&2) op=(old&~0x02) | (op&0x02); 00168 } 00169 } 00170 } 00171 00172 // -- cN2Prov7101 ---------------------------------------------------------------- 00173 00174 static cN2ProvLinkReg<cN2Prov4101,0x7101,(N2FLAG_POSTAU)> staticPL7101;