⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sc-videoguard2.c

📁 linux softcam emulator for using with vdr.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Softcam plugin to VDR (C++) * * This code is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This code is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Or, point your browser to http://www.gnu.org/copyleft/gpl.html */#include <stdio.h>#include <stdlib.h>#include <string.h>#include "system-common.h"#include "smartcard.h"#include "data.h"#include "crypto.h"#include "misc.h"#include "parse.h"#include "helper.h"#include "log-sc.h"#define SYSTEM_VIDEOGUARD2   0x0900#define SYSTEM_NAME          "SC-VideoGuard2"#define SYSTEM_PRI           -5#define SC_NAME "VideoGuard2"#define SC_ID   MAKE_SC_ID('V','i','G','2')#define L_SC        17#define L_SC_ALL    LALL(L_SC_LASTDEF)static const struct LogModule lm_sc = {  (LMOD_ENABLE|L_SC_ALL)&LOPT_MASK,  (LMOD_ENABLE|L_SC_DEFDEF)&LOPT_MASK,  "sc-videoguard2",  { L_SC_DEFNAMES }  };ADD_MODULE(L_SC,lm_sc)// -- cSystemScVideoGuard2 ---------------------------------------------------------------class cSystemScVideoGuard2 : public cSystemScCore {public:  cSystemScVideoGuard2(void);  };cSystemScVideoGuard2::cSystemScVideoGuard2(void):cSystemScCore(SYSTEM_NAME,SYSTEM_PRI,SC_ID,"SC VideoGuard2"){  hasLogger=true;}// -- cSystemLinkScVideoGuard2 --------------------------------------------------------class cSystemLinkScVideoGuard2 : public cSystemLink {public:  cSystemLinkScVideoGuard2(void);  virtual bool CanHandle(unsigned short SysId);  virtual cSystem *Create(void) { return new cSystemScVideoGuard2; }  };static cSystemLinkScVideoGuard2 staticInit;cSystemLinkScVideoGuard2::cSystemLinkScVideoGuard2(void):cSystemLink(SYSTEM_NAME,SYSTEM_PRI){}bool cSystemLinkScVideoGuard2::CanHandle(unsigned short SysId){  bool res=false;  cSmartCard *card=smartcards.LockCard(SC_ID);  if(card) {    res=card->CanHandle(SysId);    smartcards.ReleaseCard(card);    }  return res;}// -- cSmartCardDataVideoGuard2 -----------------------------------------------------enum eDataType { dtBoxId, dtSeed };class cSmartCardDataVideoGuard2 : public cSmartCardData {public:  eDataType type;  unsigned char boxid[4];  unsigned char seed0[64], seed1[64];  //  cSmartCardDataVideoGuard2(void);  cSmartCardDataVideoGuard2(eDataType Type);  virtual bool Parse(const char *line);  virtual bool Matches(cSmartCardData *param);  };cSmartCardDataVideoGuard2::cSmartCardDataVideoGuard2(void):cSmartCardData(SC_ID){}cSmartCardDataVideoGuard2::cSmartCardDataVideoGuard2(eDataType Type):cSmartCardData(SC_ID){  type=Type;}bool cSmartCardDataVideoGuard2::Matches(cSmartCardData *param){  cSmartCardDataVideoGuard2 *cd=(cSmartCardDataVideoGuard2 *)param;  return cd->type==type;}bool cSmartCardDataVideoGuard2::Parse(const char *line){  line=skipspace(line);  if(!strncasecmp(line,"BOXID",5))     { type=dtBoxId; line+=5; }  else if(!strncasecmp(line,"SEED",4)) { type=dtSeed; line+=4; }  else {    PRINTF(L_CORE_LOAD,"smartcarddatavideoguard2: format error: datatype");    return false;    }  line=skipspace(line);  switch(type) {    case dtBoxId:      if(GetHex(line,boxid,sizeof(boxid))!=sizeof(boxid)) {        PRINTF(L_CORE_LOAD,"smartcarddatavideoguard2: format error: boxid");        return false;        }      break;    case dtSeed:      if(GetHex(line,seed0,sizeof(seed0))!=sizeof(seed0)) {        PRINTF(L_CORE_LOAD,"smartcarddatacryptoworks: format error: seed0");        return false;        }      line=skipspace(line);      if(GetHex(line,seed1,sizeof(seed1))!=sizeof(seed1)) {        PRINTF(L_CORE_LOAD,"smartcarddatacryptoworks: format error: seed1");        return false;        }      break;    }  return true;}// -- cCamCryptVG2 -------------------------------------------------------------#define xor16(v1,v2,d) xxor((d),16,(v1),(v2))#define val_by2on3(x)  ((0xaaab*(x))>>16) //fixed point *2/3class cCamCryptVG2 : private cAES {private:  unsigned short cardkeys[3][32];  unsigned char stateD3A[16];  //  void LongMult(unsigned short *pData, unsigned short *pLen, unsigned int mult, unsigned int carry);  void PartialMod(unsigned short val, unsigned int count, unsigned short *outkey, const unsigned short *inkey);  void RotateRightAndHash(unsigned char *p);  void Reorder16A(unsigned char *dest, const unsigned char *src);  void ReorderAndEncrypt(unsigned char *p);  //  void Process_D0(const unsigned char *ins, unsigned char *data, const unsigned char *status);  void Process_D1(const unsigned char *ins, unsigned char *data, const unsigned char *status);  void Decrypt_D3(unsigned char *ins, unsigned char *data, const unsigned char *status);public:  void PostProcess_Decrypt(unsigned char *buff, int len, unsigned char *cw1, unsigned char *cw2);  void SetSeed(const unsigned char *Key1, const unsigned char *Key2);  void GetCamKey(unsigned char *buff);};void cCamCryptVG2::SetSeed(const unsigned char *Key1, const unsigned char *Key2){  memcpy(cardkeys[1],Key1,sizeof(cardkeys[1]));  memcpy(cardkeys[2],Key2,sizeof(cardkeys[2]));}void cCamCryptVG2::GetCamKey(unsigned char *buff){  unsigned short *tb2=(unsigned short *)buff, c=1;  memset(tb2,0,64);  tb2[0]=1;  for(int i=0; i<32; i++) LongMult(tb2,&c,cardkeys[1][i],0);}void cCamCryptVG2::PostProcess_Decrypt(unsigned char *buff, int len, unsigned char *cw1, unsigned char *cw2){  switch(buff[0]) {    case 0xD0:      Process_D0(buff,buff+5,buff+buff[4]+5);      break;    case 0xD1:      Process_D1(buff,buff+5,buff+buff[4]+5);      break;    case 0xD3:      Decrypt_D3(buff,buff+5,buff+buff[4]+5);      if(buff[1]==0x54) {        memcpy(cw1,buff+5,8);        for(int ind=14; ind<len+5;) {          if(buff[ind]==0x25) {            memcpy(cw2,buff+5+ind+2,8);            break;            }          if(buff[ind+1]==0) break;          ind+=buff[ind+1];          }        }      break;    }}void cCamCryptVG2::Process_D0(const unsigned char *ins, unsigned char *data, const unsigned char *status){  switch(ins[1]) {    case 0xb4:      memcpy(cardkeys[0],data,sizeof(cardkeys[0]));      break;    case 0xbc:       {      unsigned short *idata=(unsigned short *)data;      const unsigned short *key1=(const unsigned short *)cardkeys[1];      unsigned short key2[32];      memcpy(key2,cardkeys[2],sizeof(key2));      for(int count2=0; count2<32; count2++) {        unsigned int rem=0, div=key1[count2];        for(int i=31; i>=0; i--) {          unsigned int x=idata[i] | (rem<<16);          rem=(x%div)&0xffff;          }        unsigned int carry=1, t=val_by2on3(div) | 1;        while(t) {          if(t&1) carry=((carry*rem)%div)&0xffff;          rem=((rem*rem)%div)&0xffff;          t>>=1;          }        PartialMod(carry,count2,key2,key1);        }      unsigned short idatacount=0;      for(int i=31; i>=0; i--) LongMult(idata,&idatacount,key1[i],key2[i]);      unsigned char stateD1[16];      Reorder16A(stateD1,data);      cAES::SetKey(stateD1);      break;      }  }}void cCamCryptVG2::Process_D1(const unsigned char *ins, unsigned char *data, const unsigned char *status){  unsigned char iter[16], tmp[16];  memset(iter,0,sizeof(iter));  memcpy(iter,ins,5);  xor16(iter,stateD3A,iter);  memcpy(stateD3A,iter,sizeof(iter));  int datalen=status-data;  int datalen1=datalen;  if(datalen<0) datalen1+=15;  int blocklen=datalen1>>4;  for(int i=0,iblock=0; i<blocklen+2; i++,iblock+=16) {    unsigned char in[16];    if(blocklen==i) {      memset(in,0,sizeof(in));      memcpy(in,&data[iblock],datalen-(datalen1&~0xf));      }    else if(blocklen+1==i) {      memset(in,0,sizeof(in));      memcpy(&in[5],status,2);      }    else      memcpy(in,&data[iblock],sizeof(in));    xor16(iter,in,tmp);    ReorderAndEncrypt(tmp);    xor16(tmp,stateD3A,iter);    }  memcpy(stateD3A,tmp,16);}void cCamCryptVG2::Decrypt_D3(unsigned char *ins, unsigned char *data, const unsigned char *status){  if(ins[4]>16) ins[4]-=16;  if(ins[1]==0xbe) memset(stateD3A,0,sizeof(stateD3A));  unsigned char tmp[16];  memset(tmp,0,sizeof(tmp));  memcpy(tmp,ins,5);  xor16(tmp,stateD3A,stateD3A);  int len1=ins[4];  int blocklen=len1>>4;  if(ins[1]!=0xbe) blocklen++;  unsigned char iter[16], states[16][16];  memset(iter,0,sizeof(iter));  for(int blockindex=0; blockindex<blocklen; blockindex++) {    iter[0]+=blockindex;    xor16(iter,stateD3A,iter);    ReorderAndEncrypt(iter);    xor16(iter,&data[blockindex*16],states[blockindex]);    if(blockindex==(len1>>4)) {      int c=len1-(blockindex*16);      if(c<16) memset(&states[blockindex][c],0,16-c);      }    xor16(states[blockindex],stateD3A,stateD3A);    RotateRightAndHash(stateD3A);    }  memset(tmp,0,sizeof(tmp));  memcpy(tmp+5,status,2);  xor16(tmp,stateD3A,stateD3A);  ReorderAndEncrypt(stateD3A);  memcpy(stateD3A,status-16,sizeof(stateD3A));  ReorderAndEncrypt(stateD3A);  memcpy(data,states[0],len1);  if(ins[1]==0xbe) {    Reorder16A(tmp,states[0]);    cAES::SetKey(tmp);    }}void cCamCryptVG2::ReorderAndEncrypt(unsigned char *p){  unsigned char tmp[16];  Reorder16A(tmp,p); cAES::Encrypt(tmp,16,tmp); Reorder16A(p,tmp);}// reorder AAAABBBBCCCCDDDD to ABCDABCDABCDABCDvoid cCamCryptVG2::Reorder16A(unsigned char *dest, const unsigned char *src){  for(int i=0,k=0; i<4; i++)    for(int j=i; j<16; j+=4,k++)      dest[k]=src[j];}void cCamCryptVG2::LongMult(unsigned short *pData, unsigned short *pLen, unsigned int mult, unsigned int carry){  for(int i=0; i<*pLen; i++) {    carry+=pData[i]*mult;    pData[i]=(unsigned short)carry;    carry>>=16;    }  if(carry) pData[(*pLen)++]=carry;}void cCamCryptVG2::PartialMod(unsigned short val, unsigned int count, unsigned short *outkey, const unsigned short *inkey){  if(count) {    unsigned int mod=inkey[count];    unsigned short mult=(inkey[count]-outkey[count-1])&0xffff;    for(unsigned int i=0,ib1=count-2; i<count-1; i++,ib1--) {      unsigned int t=(inkey[ib1]*mult)%mod;      mult=t-outkey[ib1];      if(mult>t) mult+=mod;      }    mult+=val;    if((val>mult) || (mod<mult)) mult-=mod;    outkey[count]=(outkey[count]*mult)%mod;    }  else     outkey[0]=val;}static const unsigned char table1[256] = {  0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5, 0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,  0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0, 0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,  0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc, 0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,  0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a, 0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,  0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0, 0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,  0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b, 0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,  0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85, 0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,  0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5, 0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,  0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17, 0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,  0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88, 0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,  0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c, 0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,  0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9, 0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,  0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6, 0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,  0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e, 0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,  0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94, 0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,  0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68, 0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16,  };void cCamCryptVG2::RotateRightAndHash(unsigned char *p){  unsigned char t1=p[15];  for(int i=0; i<16; i++) {    unsigned char t2=t1;    t1=p[i]; p[i]=table1[(t1>>1)|((t2&1)<<7)];    }}// -- cCmdTable ----------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -