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

📄 nagra2.c

📁 linux softcam emulator for using with vdr.
💻 C
📖 第 1 页 / 共 3 页
字号:
  MonMul(B,Qx,B);  BN_copy(A,B);  ModSub(B,D,B);  ModAdd(B,Px,B,D);  BN_copy(sC0,B);  MonMul(I,Pz,B);  if(temp==0) BN_copy(Pz,I); else BN_copy(sA0,I);  MonMul(B,B,B);  BN_copy(sE0,B);  ModAdd(A,Px,A,D);  MonMul(A,A,B);  BN_copy(s100,A);  MonMul(B,sA0,Qy);  BN_copy(sA0,B);  ModSub(B,D,B);  ModAdd(B,Py,B,D);  BN_copy(s120,B);  MonMul(B,B,B);  BN_swap(A,B);  ModSub(B,D,B);  ModAdd(B,A,B,D);  if(temp==0) BN_copy(Px,B); else BN_copy(sA0,B);  ModAdd(B,B,B,D);  ModSub(B,D,B);  ModAdd(B,B,s100,D);  ModAdd(A,sA0,Py,D);  MonMul(sA0,s120,B);  MonMul(B,sE0,sC0);  MonMul(B,A,B);  ModSub(B,D,B);  ModAdd(B,B,sA0,D);  MonMul(B,s140,B);  if(temp==0) BN_copy(Py,B); else BN_copy(sA0,B);}void cMapCore::ToProjective(int set, BIGNUM *x, BIGNUM *y){  if(set==0) {    BN_set_word(I,1); MonMul(Pz,I,B);    BN_copy(Qz,Pz);    MonMul(Px,x,B);    MonMul(Py,y,B);    }  else {    MonMul(Qx,x,B);    MonMul(Qy,y,B);    }}void cMapCore::ToAffine(void){  BN_set_word(I,1);  MonMul(B,Pz,Pz); MonMul(B,Pz,B); MonMul(B,I,B);  MonExpNeg();  BN_set_word(I,1);  MonMul(A,Py,B); MonMul(Py,I,A);  MonMul(B,Pz,B); MonMul(B,Px,B); MonMul(Px,I,B);}void cMapCore::CurveInit(BIGNUM *a){  BN_zero(Px); BN_zero(Py); BN_zero(Pz); BN_zero(Qx); BN_zero(Qy); BN_zero(Qz);  BN_zero(sA0); BN_zero(sC0); BN_zero(sE0); BN_zero(s100);  BN_zero(s120); BN_zero(s140); BN_zero(s160);  MonInit();  BN_copy(A,B);  BN_copy(I,D);  BN_add_word(I,1);  BN_rshift(I,I,1);  MonMul(s140,I,B);  MonMul(s160,B,a);}bool cMapCore::DoMap(int f, unsigned char *data, int l){  const int l1=l?l:wordsize;  const int dl=l1<<3;  cycles=0;  switch(f) {    case SETSIZE:      wordsize=l; cycles=475-6; break;    case IMPORT_J:      cycles=890-6;      // fall through    case IMPORT_A:    case IMPORT_B:    case IMPORT_C:    case IMPORT_D:      if(!cycles) cycles=771+160*l1-6+(l==0?4:0);      last=f-IMPORT_J;      // fall through    case IMPORT_LAST:      if(!cycles) cycles=656+160*l-6; // Even for 'J' cycles is dependent on 'l'      regs[last]->GetLE(data,last>0?dl:8);      break;    case EXPORT_J:      cycles=897-6;      // fall through    case EXPORT_A:    case EXPORT_B:    case EXPORT_C:    case EXPORT_D:      if(!cycles) cycles=778+160*l1-6+(l==0?4:0);      last=f-EXPORT_J;      // fall through    case EXPORT_LAST:      if(!cycles) cycles=668+160*l-6; // Even for 'J' cycles is dependent on 'l'      regs[last]->PutLE(data,last>0?dl:8);      break;    case SWAP_A:    case SWAP_B:    case SWAP_C:    case SWAP_D:      cycles=776+248*l1-6;      last=f-SWAP_A+1;      x.GetLE(data,dl);      regs[last]->PutLE(data,dl);      BN_copy(*regs[last],x);      break;    case CLEAR_A:    case CLEAR_B:    case CLEAR_C:    case CLEAR_D:      cycles=467+5*l1-6;      last=f-CLEAR_A+1; BN_zero(*regs[last]);      break;    case COPY_A_B:      last=2; BN_copy(B,A); cycles=467+5*l1-6; break;    case COPY_B_A:      last=1; BN_copy(A,B); cycles=467+5*l1-6; break;    case COPY_A_C:      last=3; BN_copy(C,A); cycles=467+5*l1-6; break;    case COPY_C_A:      last=1; BN_copy(A,C); cycles=467+5*l1-6; break;    case COPY_C_D:      last=4; BN_copy(D,C); cycles=467+5*l1-6; break;    case COPY_D_C:      last=3; BN_copy(C,D); cycles=467+5*l1-6; break;    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 ------------------------------------------------------------------cN2Prov::cN2Prov(int Id, int Flags){  keyValid=false; id=Id|0x100; flags=Flags; seedSize=5;}void cN2Prov::PrintCaps(int c){  PRINTF(c,"provider %04x capabilities%s%s%s%s%s",id,           HasFlags(N2FLAG_MECM)    ?" MECM":"",           HasFlags(N2FLAG_Bx)      ?" Bx":"",           HasFlags(N2FLAG_Ex)      ?" Ex":"",           HasFlags(N2FLAG_POSTAU)  ?" POSTPROCAU":"",           HasFlags(N2FLAG_INV)     ?" INVCW":"");}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, const unsigned char *ed, unsigned char *cw){  unsigned char hd[32], 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];  DynamicHD(hd,ed);  if(keyValid && !memcmp(seed,hd,seedSize)) {	// 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,seedSize);    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);    }}// -- cN2Providers -------------------------------------------------------------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::cN2ProvLink(int Id, int Flags){  id=Id; flags=Flags;  cN2Providers::Register(this);}// -- 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;    }  // Calculate P  idata[0] |= 0x80;  idata[47] |= 1;  BN_bin2bn(idata,48,p);  BN_add_word(p,(key[21] << 5 ) | ((key[22] & 0xf0) >> 3));  // Calculate Q  idata[48] |= 0x80;  idata[95] |= 1;  BN_bin2bn(idata+48,48,q);  BN_add_word(q,(key[22] &0xf << 9 ) | (key[23]<<1));}bool cNagra2::Signature(const unsigned char *vkey, const unsigned char *sig, const unsigned char *msg, int len){  unsigned char buff[16];  memcpy(buff,vkey,sizeof(buff));  for(int i=0; i<len; i+=8) {    IdeaKS ks;    idea.SetEncKey(buff,&ks);    memcpy(buff,buff+8,8);    idea.Encrypt(msg+i,8,buff+8,&ks,0);    xxor(&buff[8],8,&buff[8],msg+i);    }  buff[8]&=0x7F;  return (memcmp(sig,buff+8,8)==0);}bool cNagra2::DecryptECM(const unsigned char *in, unsigned char *out, const unsigned char *key, int len, const unsigned char *vkey, BIGNUM *m){  int sign=in[0] & 0x80;  if(rsa.RSA(out,in+1,64,pubExp,m)<=0) {    PRINTF(L_SYS_CRYPTO,"first RSA failed (ECM)");    return false;    }  out[63]|=sign; // sign adjustment  if(len>64) memcpy(out+64,in+65,len-64);  if(in[0]&0x04) {    unsigned char tmp[8];    DES_key_schedule ks1, ks2;     RotateBytes(tmp,&key[0],8);    DES_key_sched((DES_cblock *)tmp,&ks1);    RotateBytes(tmp,&key[8],8);    DES_key_sched((DES_cblock *)tmp,&ks2);    memset(tmp,0,sizeof(tmp));    for(int i=7; i>=0; i--) RotateBytes(out+8*i,8);    DES_ede2_cbc_encrypt(out,out,len,&ks1,&ks2,(DES_cblock *)tmp,DES_DECRYPT);    for(int i=7; i>=0; i--) RotateBytes(out+8*i,8);    }   else idea.Decrypt(out,len,key,0);   RotateBytes(out,64);  if(rsa.RSA(out,out,64,pubExp,m,false)<=0) {    PRINTF(L_SYS_CRYPTO,"second RSA failed (ECM)");    return false;    }  if(vkey && !Signature(vkey,out,out+8,len-8)) {    PRINTF(L_SYS_CRYPTO,"signature failed (ECM)");    return false;    }  return true;}bool cNagra2::DecryptEMM(const unsigned char *in, unsigned char *out, const unsigned char *key, int len, const unsigned char *vkey, BIGNUM *m)

⌨️ 快捷键说明

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