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

📄 nagra2.c

📁 这是一个LINUX环境的 VDR 插件源代码,可支持Irdeto, Seca, Viaccess, Nagra, Conax & Cryptoworks等CA系统的读卡、共享等操作。
💻 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.h"#include "misc.h"#include "opts.h"#include "network.h"#include "crypto.h"#include "helper.h"#include <openssl/des.h>#include <openssl/sha.h>#include "openssl-compat.h"#include "nagra.h"#include "cpu.h"#include "log-nagra.h"#define SYSTEM_NAME          "Nagra2"#define SYSTEM_PRI           -10// -- cN2Emu -------------------------------------------------------------------class cN2Emu : protected c6805 {private:  bool initDone;protected:  bool Init(int id, int romv);  virtual void Stepper(void) {}public:  cN2Emu(void);  virtual ~cN2Emu() {}  };cN2Emu::cN2Emu(void){  initDone=false;}bool cN2Emu::Init(int id, int romv){  if(!initDone) {    ResetMapper();    char buff[256];    snprintf(buff,sizeof(buff),"ROM%d.bin",romv);    // UROM  0x00:0x4000-0x7fff    if(!AddMapper(new cMapRom(0x4000,buff,0x00000),0x4000,0x4000,0x00)) return false;    // ROM00 0x00:0x8000-0xffff    if(!AddMapper(new cMapRom(0x8000,buff,0x04000),0x8000,0x8000,0x00)) return false;    // ROM01 0x01:0x8000-0xffff    if(!AddMapper(new cMapRom(0x8000,buff,0x0C000),0x8000,0x8000,0x01)) return false;    // ROM02 0x02:0x8000-0xbfff    if(!AddMapper(new cMapRom(0x8000,buff,0x14000),0x8000,0x4000,0x02)) return false;    snprintf(buff,sizeof(buff),"EEP%02X_%d.bin",(id>>8)&0xFF,romv);    // Eeprom00 0x00:0x3000-0x37ff OTP 0x80    if(!AddMapper(new cMapRom(0x3000,buff,0x0000),0x3000,0x0800,0x00)) return false;    //XXX if(!AddMapper(new cMapEeprom(0x3000,buff,128,0x0000),0x3000,0x0800,0x00)) return false;    // Eeprom80 0x80:0x8000-0xbfff    if(!AddMapper(new cMapRom(0x8000,buff,0x0800),0x8000,0x4000,0x80)) return false;    //XXX if(!AddMapper(new cMapEeprom(0x8000,buff,  0,0x0800),0x8000,0x4000,0x80)) return false;    initDone=true;    }  return true;}// -- cMapCore -----------------------------------------------------------------#define SETSIZE  0x02#define IMPORT_J 0x03#define IMPORT_A 0x04#define IMPORT_B 0x05#define IMPORT_C 0x06#define IMPORT_D 0x07#define EXPORT_A 0x0A#define EXPORT_B 0x0B#define EXPORT_C 0x0C#define EXPORT_D 0x0Dclass cMapCore {private:  cBN x, y, s, j;  SHA_CTX sctx;protected:  cBN A, B, C, D, J;  cBN H, R;  cBNctx ctx;  int wordsize;  //  void ImportReg(unsigned char reg, const unsigned char *data, int l=0);  void ExportReg(unsigned char reg, unsigned char *data, int l=0, bool BE=false);  void SetWordSize(int l) { wordsize=l; }  void MakeJ(void);  void MonMul(BIGNUM *o, BIGNUM *i1, BIGNUM *i2);  bool DoMap(int f, unsigned char *data=0, int l=0);public:  cMapCore(void);  };cMapCore::cMapCore(void){  wordsize=4;}void cMapCore::ImportReg(unsigned char reg, const unsigned char *in, int l){  l=(l?l:wordsize)<<3;  switch(reg) {    case IMPORT_J: J.GetLE(in,8); break;    case IMPORT_A: A.GetLE(in,l); break;    case IMPORT_B: B.GetLE(in,l); break;    case IMPORT_C: C.GetLE(in,l); break;    case IMPORT_D: D.GetLE(in,l); break;    default: PRINTF(L_GEN_DEBUG,"internal: nagramap import register not supported"); return;    }}void cMapCore::ExportReg(unsigned char reg, unsigned char *out, int l, bool BE){  l=(l?l:wordsize)<<3;  cBN *ptr;  switch(reg) {    case EXPORT_A: ptr=&A; break;    case EXPORT_B: ptr=&B; break;    case EXPORT_C: ptr=&C; break;    case EXPORT_D: ptr=&D; break;    default: PRINTF(L_GEN_DEBUG,"internal: nagramap export register not supported"); return;    }  if(!BE) ptr->PutLE(out,l);  else ptr->Put(out,l);}void cMapCore::MakeJ(void){#if OPENSSL_VERSION_NUMBER < 0x0090700fL#error BN_mod_inverse is probably buggy in your openssl version#endif  BN_zero(x);  BN_sub(J,x,D);  BN_set_bit(J,0);  BN_set_bit(x,64);  BN_mod_inverse(J,J,x,ctx);}void cMapCore::MonMul(BIGNUM *o, BIGNUM *i1, BIGNUM *i2){  int words=(BN_num_bytes(i1)+7)>>3;  BN_zero(s);  for(int i=0; i<words; i++) {	    BN_rshift(x,i1,i<<6);    BN_mask_bits(x,64);    BN_mul(x,x,i2,ctx);    BN_add(s,s,x);    BN_copy(x,s);    BN_mask_bits(x,64);    BN_mul(x,x,J,ctx);    if(i==(words-1)) {      BN_lshift(y,x,64);      BN_add(y,y,x);      // Low      BN_rshift(C,y,2);      BN_add(C,C,s);      BN_rshift(C,C,52);      BN_mask_bits(C,12);      }    BN_mask_bits(x,64);    BN_mul(x,x,D,ctx);    BN_add(s,s,x);    if(i==(words-1)) {      // High      BN_lshift(y,s,12);      BN_add(C,C,y);      BN_mask_bits(C,wordsize<<6);      }    BN_rshift(s,s,64);    if(BN_cmp(s,D)==1) {      BN_copy(x,s);      BN_sub(s,x,D);      }    }  BN_copy(o,s);}bool cMapCore::DoMap(int f, unsigned char *data, int l){  switch(f) {    case 0x43: // init SHA1      SHA1_Init(&sctx);      break;    case 0x44: // add 64 bytes to SHA1 buffer      RotateBytes(data,64);      SHA1_Update(&sctx,data,64);      BYTE4_LE(data   ,sctx.h4);      BYTE4_LE(data+4 ,sctx.h3);      BYTE4_LE(data+8 ,sctx.h2);      BYTE4_LE(data+12,sctx.h1);      BYTE4_LE(data+16,sctx.h0);      break;    case 0x45: // add wordsize bytes to SHA1 buffer and finalize SHA result      if(wordsize) {        if(wordsize>1) RotateBytes(data,wordsize);        SHA1_Update(&sctx,data,wordsize);        }      memset(data,0,64);      SHA1_Final(data+64,&sctx);      break;    default:      return false;    }  return true;}// -- cN2Prov ------------------------------------------------------------------class cN2Prov {private:  unsigned seed[5], cwkey[8];  bool keyValid;  cIDEA idea;protected:  int id, flags;  //  virtual bool Algo(int algo, const unsigned char *hd, unsigned char *hw) { return false; }  virtual bool NeedsCwSwap(void) { return false; }  void ExpandInput(unsigned char *hw);public:  cN2Prov(int Id, int Flags);  virtual ~cN2Prov() {}  bool MECM(unsigned char in15, int algo, unsigned char *cws);  void SwapCW(unsigned char *cw);  virtual int ProcessBx(unsigned char *data, int len, int pos) { return -1; }  virtual bool PostProcAU(int id, unsigned char *data) { return true; }  bool CanHandle(int Id) { return ((Id^id)&~0x107)==0; }  bool HasFlags(int Flags) { return (flags&Flags)==Flags; }  };cN2Prov::cN2Prov(int Id, int Flags){  keyValid=false; id=Id; flags=Flags;}void cN2Prov::ExpandInput(unsigned char *hw){  hw[0]^=(0xDE +(0xDE<<1)) & 0xFF;  hw[1]^=(hw[0]+(0xDE<<1)) & 0xFF;  for(int i=2; i<128; i++) hw[i]^=hw[i-2]+hw[i-1];  IdeaKS ks;  idea.SetEncKey((unsigned char *)"NagraVision S.A.",&ks);  unsigned char buf[8];  memset(buf,0,8);  for(int i=0; i<128; i+=8) {    xxor(buf,8,buf,&hw[i]);    idea.Encrypt(buf,8,buf,&ks,0);    xxor(buf,8,buf,&hw[i]);    memcpy(&hw[i],buf,8);    }}bool cN2Prov::MECM(unsigned char in15, int algo, unsigned char *cw){  unsigned char hd[5], hw[128+64], buf[20];  hd[0]=in15&0x7F;  hd[1]=cw[14];  hd[2]=cw[15];  hd[3]=cw[6];  hd[4]=cw[7];  if(keyValid && !memcmp(seed,hd,5)) {	// key cached    memcpy(buf,cwkey,8);    }  else {				// key not cached    memset(hw,0,sizeof(hw));    if(!Algo(algo,hd,hw)) return false;    memcpy(&hw[128],hw,64);    RotateBytes(&hw[64],128);    SHA1(&hw[64],128,buf);    RotateBytes(buf,20);    memcpy(seed,hd,5);    memcpy(cwkey,buf,8);    keyValid=true;    }    memcpy(&buf[8],buf,8);  IdeaKS ks;  idea.SetEncKey(buf,&ks);  memcpy(&buf[0],&cw[8],6);  memcpy(&buf[6],&cw[0],6);  idea.Encrypt(&buf[4],8,&buf[4],&ks,0);  idea.Encrypt(buf,8,buf,&ks,0);  memcpy(&cw[ 0],&buf[6],3);  memcpy(&cw[ 4],&buf[9],3);  memcpy(&cw[ 8],&buf[0],3);  memcpy(&cw[12],&buf[3],3);  for(int i=0; i<16; i+=4) cw[i+3]=cw[i]+cw[i+1]+cw[i+2];  return true;}void cN2Prov::SwapCW(unsigned char *cw){  if(NeedsCwSwap()) {    unsigned char tt[8];    memcpy(&tt[0],&cw[0],8);    memcpy(&cw[0],&cw[8],8);    memcpy(&cw[8],&tt[0],8);    }}// -- cN2ProvLink & cN2Providers -----------------------------------------------#define N2FLAG_NONE     0#define N2FLAG_MECM     1#define N2FLAG_Bx       2#define N2FLAG_POSTAU   4#define N2FLAG_INV      128class cN2Providers;class cN2ProvLink {friend class cN2Providers;private:  cN2ProvLink *next;protected:  int id, flags;  //  virtual cN2Prov *Create(void)=0;  bool CanHandle(int Id) { return ((Id^id)&~0x107)==0; }  bool HasFlags(int Flags) { return (flags&Flags)==Flags; }public:  cN2ProvLink(int Id, int Flags);  virtual ~cN2ProvLink() {}  };class cN2Providers {friend class cN2ProvLink;private:  static cN2ProvLink *first;  //  static void Register(cN2ProvLink *plink);public:  static cN2Prov *GetProv(int Id, int Flags);  };template<class PROV, int ID, int FLAGS> class cN2ProvLinkReg : public cN2ProvLink {public:  cN2ProvLinkReg(void):cN2ProvLink(ID,FLAGS) {}  virtual cN2Prov *Create(void) { return new PROV(id,flags); }  };cN2ProvLink *cN2Providers::first=0;void cN2Providers::Register(cN2ProvLink *plink){  PRINTF(L_CORE_DYN,"n2providers: registering prov %04X with flags %d",plink->id,plink->flags);  plink->next=first;  first=plink;}cN2Prov *cN2Providers::GetProv(int Id, int Flags){  cN2ProvLink *pl=first;  while(pl) {    if(pl->CanHandle(Id) && pl->HasFlags(Flags)) return pl->Create();    pl=pl->next;    }  return 0;}cN2ProvLink::cN2ProvLink(int Id, int Flags){  id=Id; flags=Flags;  cN2Providers::Register(this);}#include "nagra2-prov.c"#ifndef TESTER// -- cNagra2 ------------------------------------------------------------------class cNagra2 : public cNagra {private:  bool Signature(const unsigned char *vkey, const unsigned char *sig, const unsigned char *msg, int len);protected:  cIDEA idea;  //  virtual void CreatePQ(const unsigned char *key, BIGNUM *p, BIGNUM *q);  bool DecryptECM(const unsigned char *in, unsigned char *out, const unsigned char *key, int len, const unsigned char *vkey, BIGNUM *m);  bool DecryptEMM(const unsigned char *in, unsigned char *out, const unsigned char *key, int len, const unsigned char *vkey, BIGNUM *m);  };void cNagra2::CreatePQ(const unsigned char *key, BIGNUM *p, BIGNUM *q){  // Calculate P and Q from PK  IdeaKS ks;  idea.SetEncKey(key,&ks);  // expand IDEA-G key  unsigned char idata[96];  for(int i=11; i>=0; i--) {    unsigned char *d=&idata[i*8];    memcpy(d,&key[13],8);    *d^=i;    idea.Decrypt(d,8,&ks,0);    xxor(d,8,d,&key[13]);    *d^=i;    }

⌨️ 快捷键说明

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