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

📄 nagra2.c

📁 linux softcam emulator for using with vdr.
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * 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 "opts.h"#include "nagra.h"#include "nagra2.h"#define SYSTEM_NAME          "Nagra2"#define SYSTEM_PRI           -10// -- cN2Timer -----------------------------------------------------------------cN2Timer::cN2Timer(void){  cycles=0; ctrl=0; divisor=1; remainder=-1; latch=0xFF;}void cN2Timer::AddCycles(unsigned int count){  if(Running()) {    remainder+=count;    if(remainder>=divisor) {      cycles-=remainder/divisor;      remainder%=divisor;      }    if(ctrl&tmCONTINUOUS) {      while(cycles<0) cycles+=latch+1;      }    else if(cycles<0 || (cycles==0 && remainder>=4)) {      cycles=0;      Stop();      }    }}void cN2Timer::Latch(unsigned char val){  if(!Running()) {    latch=val; if(latch==0) latch=0x100;    cycles=latch; remainder=0;    ctrl|=tmLATCHED;    }}void cN2Timer::Ctrl(unsigned char val){  if(Running()) {    ctrl=(ctrl&~tmRUNNING) | (val&tmRUNNING);    if(!Running()) {      Stop();      PRINTF(L_SYS_EMU,"n2timer: stopped cycles=%x ctrl=%x",cycles,ctrl);      }    }  else {    ctrl=(ctrl&~tmMASK) | (val&tmMASK);    if(Running()) {      if((ctrl&0xc0)==0x40) divisor=1 << (2 *(1 + ((ctrl & 0x38) >> 3)));      else divisor=4; // This is wrong, but we haven't figured the right value out yet      if(divisor<=0) divisor=1; // sanity      if(!(ctrl&tmLATCHED)) cycles=(unsigned int)(cycles-1)&0xFF;      PRINTF(L_SYS_EMU,"n2timer: started latch=%x div=%d cycles=%x ctrl=%x",latch,divisor,cycles,ctrl);      remainder=-1;      if(!(ctrl&tmCONTINUOUS) && cycles==0) ctrl&=~tmRUNNING;      }    }}void cN2Timer::Stop(void){  ctrl&=~(tmRUNNING|tmLATCHED);}// -- cMapMemHW ----------------------------------------------------------------cMapMemHW::cMapMemHW(void):cMapMem(HW_OFFSET,HW_REGS){  cycles=0;  CRCvalue=0; CRCpos=0; CRCstarttime=0;  GenCRC16Table();  PRINTF(L_SYS_EMU,"mapmemhw: new HW map off=%04x size=%04x",offset,size);}void cMapMemHW::GenCRC16Table(void){  unsigned char hi[256];    for(int i=0; i<256; ++i) {      unsigned short c = i;      for(int j=0; j<8; ++j) c = (c>>1) ^ ((c&1) ? 0x8408 : 0); // ccitt poly      crc16table[0xff-i] = c & 0xff;      hi[i] = c>>8;      }    for(int i=0; i<32; ++i)      for(int j=0; j<8; ++j)        crc16table[i*8+j] |= hi[(0x87+(i*8)-j)&0xff]<<8;}void cMapMemHW::AddCycles(unsigned int num){  cycles+=num;  for(int i=0; i<MAX_TIMERS; i++) timer[i].AddCycles(num);}unsigned char cMapMemHW::Get(unsigned short ea){  if(ea<offset || ea>=offset+size) return 0;  ea-=offset;  switch(ea) {    case HW_SECURITY:      return 0x0F;    case HW_TIMER0_CONTROL:    case HW_TIMER1_CONTROL:    case HW_TIMER2_CONTROL:      return timer[TIMER_NUM(ea)].Ctrl();    case HW_TIMER0_DATA:    case HW_TIMER1_DATA:    case HW_TIMER2_DATA:      return timer[TIMER_NUM(ea)].Cycles();    case HW_TIMER0_LATCH:    case HW_TIMER1_LATCH:    case HW_TIMER2_LATCH:      return timer[TIMER_NUM(ea)].Latch();    case HW_CRC_CONTROL:      {      unsigned char r=mem[ea];      if(!(r&CRC_DISABLED) && cycles-CRCstarttime<CRCCALC_DELAY) r|=CRC_BUSY; // busy      else r&=~CRC_BUSY; // not busy      return r;      }    case HW_CRC_DATA:      {      unsigned char r=CRCvalue>>((CRCpos&1)<<3);      CRCpos=!CRCpos;      return r;      }    default:      return mem[ea];    }}void cMapMemHW::Set(unsigned short ea, unsigned char val){  if(ea<offset || ea>=offset+size) return;  ea-=offset;  switch(ea) {    case HW_SECURITY:      break;    case HW_TIMER0_CONTROL:    case HW_TIMER1_CONTROL:    case HW_TIMER2_CONTROL:      timer[TIMER_NUM(ea)].Ctrl(val);      break;    case HW_TIMER0_LATCH:    case HW_TIMER1_LATCH:    case HW_TIMER2_LATCH:      timer[TIMER_NUM(ea)].Latch(val);      break;    case HW_CRC_CONTROL:      mem[ea]=val;      if(!(val&CRC_DISABLED)) {        CRCvalue=0; CRCpos=0;        CRCstarttime=cycles-CRCCALC_DELAY;        }      break;    case HW_CRC_DATA:      if(!(mem[HW_CRC_CONTROL]&CRC_DISABLED) && cycles-CRCstarttime>=CRCCALC_DELAY) {        CRCvalue=(CRCvalue>>8)^crc16table[(CRCvalue^val)&0xFF];        CRCpos=0;        CRCstarttime=cycles;        }      break;    default:      mem[ea]=val;      break;    }}// -- 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,romv>=110?0x8000:0x4000,0x02)) return false;    snprintf(buff,sizeof(buff),"EEP%02X_%d.bin",(id>>8)&0xFF|0x01,romv);    // Eeprom00 0x00:0x3000-0x37ff OTP 0x80    //XXX if(!AddMapper(new cMapRom(0x3000,buff,0x0000),0x3000,0x0800,0x00)) return false;    if(!AddMapper(new cMapEeprom(0x3000,buff,128,0x0000),0x3000,0x0800,0x00)) return false;    // Eeprom80 0x80:0x8000-0xbfff    //XXX if(!AddMapper(new cMapRom(0x8000,buff,0x0800),0x8000,0x4000,0x80)) return false;    if(!AddMapper(new cMapEeprom(0x8000,buff,  0,0x0800),0x8000,0x4000,0x80)) return false;    initDone=RomInit();    }  return initDone;}// -- cMapCore -----------------------------------------------------------------cMapCore::cMapCore(void){  wordsize=4; last=1;  regs[0]=&J; regs[1]=&A; regs[2]=&B; regs[3]=&C; regs[4]=&D;}void cMapCore::ModAdd(BIGNUM *r, BIGNUM *a, BIGNUM *b, BIGNUM *d){  BN_add(r,a,b);  if(BN_cmp(r,d)>=0) BN_sub(r,r,d);  BN_mask_bits(r,wordsize<<6);}void cMapCore::ModSub(BIGNUM *r, BIGNUM *d, BIGNUM *b){  cBN p;  BN_set_bit(p,wordsize<<6);  BN_mod_sub(r,d,b,p,ctx);  BN_mask_bits(r,wordsize<<6);}void cMapCore::MakeJ0(BIGNUM *j, BIGNUM *d){#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 *a, BIGNUM *b, BIGNUM *c, BIGNUM *d, BIGNUM *j, int words){  if(!words) words=wordsize;  BN_zero(s);  for(int i=0; i<words;) {    BN_rshift(x,a,(i++)<<6);    BN_mask_bits(x,64);    BN_mul(x,x,b,ctx);    BN_add(s,s,x);    BN_copy(x,s);    BN_mask_bits(x,64);    BN_mul(x,x,j,ctx);    if(i==words) {      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) {      // 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);}void cMapCore::MonInit(int bits){  // Calculate J0 & H montgomery elements in J and B  MakeJ0(J,D);  BN_zero(I);  BN_set_bit(I,bits ? bits : 68*wordsize);  BN_mod(B,I,D,ctx);  for(int i=0; i<4; i++) MonMul(B,B,B);}void cMapCore::MonExpNeg(void){  if(BN_is_zero(D)) { BN_set_word(A,1); return; }  cBN e;  BN_copy(e,D);  BN_mask_bits(e,8);		// check LSB  unsigned int n=BN_get_word(e);  BN_copy(e,D);  if(n) BN_sub_word(e,0x02);	// N -2  else  BN_add_word(e,0xFE);	// N + 254 ('carryless' -2)  BN_copy(A,B);  for(int i=BN_num_bits(e)-2; i>-1; i--) {    MonMul(B,B,B);    if(BN_is_bit_set(e,i)) MonMul(B,A,B);    }  BN_set_word(A,1);  MonMul(B,A,B);}void cMapCore::DoubleP(int temp){  ModAdd(B,Py,Py,D);  MonMul(sC0,Pz,B);  MonMul(B,B,B);  MonMul(B,Px,B);  ModSub(sA0,D,B);  MonMul(B,Px,Px);  BN_copy(A,B);  ModAdd(B,B,B,D);  ModAdd(A,B,A,D);  MonMul(B,Pz,Pz);  MonMul(B,B,B);  MonMul(B,s160,B);  ModAdd(B,B,A,D);  BN_copy(A,B);  MonMul(B,B,B);  BN_copy(C,sA0);  ModAdd(B,C,B,D);  ModAdd(B,C,B,D);  if(temp==0) BN_copy(Px,B); else BN_copy(sA0,B);  ModAdd(B,C,B,D);  MonMul(B,A,B);  BN_copy(A,B);  MonMul(B,Py,Py);  ModAdd(B,B,B,D);  MonMul(B,B,B);  ModAdd(B,B,B,D);  ModAdd(B,B,A,D);  ModSub(B,D,B);  if(temp==0) { BN_copy(Py,B); BN_copy(Pz,sC0); }  else BN_copy(sA0,sC0);}void cMapCore::AddP(int temp){  MonMul(B,Pz,Pz);  MonMul(sA0,Pz,B);

⌨️ 快捷键说明

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