SASC
DVBSoftCAM

nagra2-4101.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 <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;
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines