📄 nagra2.c
字号:
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(!words) { // High BN_lshift(y,s,12); BN_add(c,c,y); BN_mask_bits(c,wordsize<<6); } BN_rshift(s,s,64); if(words) MonFin(s,d); if(!words) BN_copy(o,s);}void cMapMath::MonFin(BIGNUM *s, BIGNUM *d){ if(BN_cmp(s,d)>=0) BN_sub(s,s,d);}// -- cMapCore -----------------------------------------------------------------cMapCore::cMapCore(void){ last=1; mapid=0; regs[0]=&J; regs[1]=&A; regs[2]=&B; regs[3]=&C; regs[4]=&D; interruptible=false;}void cMapCore::IMakeJ(void){ AddMapCycles(19); WS_START(1); AddMapCycles(102); MakeJ0(J,D,C); AddMapCycles(303); BN_zero(C); AddMapCycles(34); WS_END(); AddMapCycles(10);}void cMapCore::IMonInit0(int bits){ AddMapCycles(132+(wordsize*8+3)/5*5); if(BN_num_bits(D)>1) AddMapCycles(54); if(!BN_is_zero(D)) { AddMapCycles(54); BN_zero(I); BN_set_bit(I,bits ? bits : 68*wordsize); BN_zero(B); AddMapCycles(141+(wordsize*8+3)/5*5); BN_set_bit(B,64*(wordsize-1)); AddMapCycles(92+72*wordsize); BN_mod(B,I,D,ctx); AddMapCycles(639); } AddMapCycles(52); for(int i=0; i<4; i++) { MonMul0(B,B,B,C,D,J,0); AddMapCycles(96+6*(i>0)); MonFin(B,D); }}void cMapCore::IMonInit(int bits){ IMakeJ(); IMonInit0(bits);}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::MonExp(BIGNUM *scalar){ if(BN_is_zero(D)) { BN_one(A); return; } BN_copy(A,B); for(int i=BN_num_bits(scalar)-2; i>-1; i--) { MonMul(B,B,B); if(BN_is_bit_set(scalar,i)) MonMul(B,A,B); } BN_one(A); MonMul(B,A,B);}void cMapCore::MonExpNeg(void){ if(BN_is_zero(D)) { BN_set_word(A,1); return; } 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); } if(BN_is_bit_set(D,0)) { int i; for(i=BN_num_bits(D)-2; i>0; i--) if(BN_is_bit_set(D,i)) break; if(i<=0) { MonMul(B,B,B); 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); 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_mask_bits(I,wordsize<<6); BN_rshift(I,I,1); MonMul(s140,I,B); MonMul(s160,B,a);}void cMapCore::PostDecryptSetup(bool ecm){ if(ecm) wordsize=0x8; else wordsize=0xC;}int cMapCore::GetOpSize(int l){ return l!=0 ? l : wordsize;}void cMapCore::DoMap(int f, unsigned char *data, int l){ PRINTF(L_SYS_MAP,"%04x: calling function %02X",mapid,f); cycles=0; unsigned int startcycles=CpuCycles(); interrupted=false; interruptible=true; try { if(!Map(f,data,l) && !MapGeneric(f,data,l)) PRINTF(L_SYS_MAP,"%04x: unsupported call %02x",mapid,f); if(cycles) { unsigned int elapsed=CpuCycles()-startcycles; if(cycles>elapsed) AddMapCycles(cycles-elapsed); } } catch(int) { interrupted=true; PRINTF(L_SYS_MAP,"%04x: call %02x interrupted (%d cycles)",mapid,f,CpuCycles()-startcycles); } interruptible=false; cycles=CpuCycles()-startcycles;}bool cMapCore::MapGeneric(int f, unsigned char *data, int l){ const int l1=GetOpSize(l); const int dl=l1<<3; switch(f) { case SETSIZE: cycles=(l>17 ? 459 : (l ? 475 : 454))-6; if(l>=1 && l<=17) wordsize=l; break; case IMPORT_J: cycles=890-6; last=0; regs[0]->GetLE(data,8); break; case IMPORT_A: case IMPORT_B: case IMPORT_C: case IMPORT_D: if(l>17) { l=17; cycles+=5; } else if(l<=0) { l=wordsize; cycles+=4; } cycles+=771+160*l-6; last=f-IMPORT_J; regs[last]->GetLE(data,l<<3); break; case IMPORT_LAST: if(l>16) { l=1; cycles+=5; } else if(l<=0) l=1; cycles=656+160*l-6; regs[last]->GetLE(data,(last==0?1:l)<<3); break; case EXPORT_J: cycles=897-6; last=0; regs[0]->PutLE(data,8); break; case EXPORT_A: case EXPORT_B: case EXPORT_C: case EXPORT_D: if(l>17) { l=17; cycles+=5; } else if(l<=0) { l=wordsize; cycles+=4; } cycles=778+160*l-6; last=f-EXPORT_J; regs[last]->PutLE(data,l<<3); break; case EXPORT_LAST: if(l>16) { l=1; cycles+=5; } else if(l<=0) l=1; cycles=668+160*l-6; regs[last]->PutLE(data,(last==0?1:l)<<3); break; case SWAP_A: case SWAP_B: case SWAP_C: case SWAP_D: cycles=776+248*l1-6; last=f-SWAP_A+1; e.GetLE(data,dl); regs[last]->PutLE(data,dl); regs[last]->Set(e,l1); break; case CLEAR_A: case CLEAR_B: case CLEAR_C: case CLEAR_D: cycles=462+(8*l1+3)/5*5-6; last=f-CLEAR_A+1; regs[last]->Clear(l1); break; case COPY_A_B: last=2; B.Set(A,l1); cycles=462+(8*l1+3)/5*5-6; break; case COPY_B_A: last=1; A.Set(B,l1); cycles=462+(8*l1+3)/5*5-6; break; case COPY_A_C: last=3; C.Set(A,l1); cycles=462+(8*l1+3)/5*5-6; break; case COPY_C_A: last=1; A.Set(C,l1); cycles=462+(8*l1+3)/5*5-6; break; case COPY_C_D: last=4; D.Set(C,l1); cycles=462+(8*l1+3)/5*5-6; break; case COPY_D_C: last=3; C.Set(D,l1); cycles=462+(8*l1+3)/5*5-6; break; case 0x39: case 0x3a: AddMapCycles(f==0x39?433:192); IMonInit(); if(f==0x39) { I.GetLE(data,wordsize<<3); MonMul(B,I,B); } else MonMul(B,A,B); MonMul(B,A,B); 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(dl) { if(dl>1) RotateBytes(data,dl); SHA1_Update(&sctx,data,dl); } SHA1_Final(data,&sctx); RotateBytes(data,20); 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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -