📄 viaccess.c
字号:
/* * 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 <string.h>#include "viaccess.h"#include "tps.h"#include "system-common.h"#include "misc.h"#include "parse.h"#include "log-viaccess.h"#define SYSTEM_NAME "Viaccess"#define SYSTEM_PRI -10#define SYSTEM_CAN_HANDLE(x) ((x)==SYSTEM_VIACCESS)static const struct LogModule lm_sys = { (LMOD_ENABLE|L_SYS_ALL)&LOPT_MASK, (LMOD_ENABLE|L_SYS_DEFDEF|L_SYS_TPS|L_SYS_TPSAU|L_SYS_TIME|L_SYS_ST20)&LOPT_MASK, "viaccess", { L_SYS_DEFNAMES,"tps","tpsau","time","st20","disasm" } };ADD_MODULE(L_SYS,lm_sys)// -- cPlainKeyVia -------------------------------------------------------------#define VIA1_KEYLEN 8#define VIA2_KEYLEN 16#define VIATPS_KEYLEN 16class cPlainKeyVia : public cPlainKeyStd {protected: virtual cString PrintKeyNr(void);public: cPlainKeyVia(bool Super); virtual bool Parse(const char *line); virtual bool SetKey(void *Key, int Keylen); virtual bool SetBinKey(unsigned char *Mem, int Keylen); };static cPlainKeyTypeReg<cPlainKeyVia,'V'> KeyReg;cPlainKeyVia::cPlainKeyVia(bool Super):cPlainKeyStd(Super){}bool cPlainKeyVia::SetKey(void *Key, int Keylen){ if(keynr==MBC3('T','P','S')) SetSupersede(false); return cPlainKeyStd::SetKey(Key,Keylen);}bool cPlainKeyVia::SetBinKey(unsigned char *Mem, int Keylen){ if(keynr==MBC3('T','P','S')) SetSupersede(false); return cPlainKeyStd::SetBinKey(Mem,Keylen);}bool cPlainKeyVia::Parse(const char *line){ unsigned char sid[3], skeynr, skey[VIA2_KEYLEN]; const char *sline=line; int len; if(GetChar(line,&type,1) && (len=GetHex(line,sid,3,false))) { type=toupper(type); id=Bin2Int(sid,len); line=skipspace(line); bool ok=false; if(!strncasecmp(line,"TPSMK",5) && line[5]>='0' && line[5]<='9') { keynr=MBC3('M','K',line[5]-'0'); line+=6; ok=(len=GetHex(line,skey,VIATPS_KEYLEN)); } else if(!strncasecmp(line,"TPS ",4)) { line+=4; keynr=MBC3('T','P','S'); ok=(len=GetHex(line,skey,VIATPS_KEYLEN)); } else if(GetHex(line,&skeynr,1)) { keynr=skeynr; ok=((len=GetHex(line,skey,VIA2_KEYLEN,false)) && (len==VIA1_KEYLEN || len==VIA2_KEYLEN)); } if(ok) { SetBinKey(skey,len); return true; } } FormatError("viaccess",sline); return false;}cString cPlainKeyVia::PrintKeyNr(void){ return cString::sprintf((keynr==MBC3('T','P','S'))?"TPS":"%02X",keynr);}// -- cViaccessCardInfo --------------------------------------------------------class cViaccessCardInfo : public cProviderViaccess, public cCardViaccess {public: unsigned char keyno, key[8]; // bool Parse(const char *line); bool Save(FILE *f) { return true; } bool IsUpdated(void) { return false; } void Updated(void) {} bool Cmp(cViaccessCardInfo *ci) { return false; } };bool cViaccessCardInfo::Parse(const char *line){ return GetHex(line,ident,sizeof(ident)) && GetHex(line,ua,sizeof(ua)) && GetHex(line,sa,sizeof(sa)) && GetHex(line,&keyno,1) && GetHex(line,key,sizeof(key));}// -- cViaccessCardInfos -------------------------------------------------------class cViaccessCardInfos : public cCardInfos<cViaccessCardInfo> {public: cViaccessCardInfos(void):cCardInfos<cViaccessCardInfo>(SYSTEM_NAME) {} };static cViaccessCardInfos Vcards;// -- cViaccess ----------------------------------------------------------------class cViaccess : protected cDes {private: unsigned char v2key[8]; bool v2mode; // int HashNanos(const unsigned char *data, int len); void Via2Mod(const unsigned char *key2, unsigned char *data);protected: unsigned char hbuff[8], hkey[8]; int pH; // void SetV2Mode(const unsigned char *key2); void SetHashKey(const unsigned char *key); void HashByte(unsigned char c); void HashClear(void); void Hash(void); // void Decode(unsigned char *data, const unsigned char *key); bool Decrypt(const unsigned char *work_key, const unsigned char *data, int len, unsigned char *des_data1, unsigned char *des_data2); // virtual unsigned int Mod(unsigned int R, unsigned int key7) const;public: cViaccess(void); };cViaccess::cViaccess(void):cDes(){ v2mode=false;}/* viaccess DES modification */unsigned int cViaccess::Mod(unsigned int R, unsigned int key7) const{ if(key7!=0) { const unsigned int key5=(R>>24)&0xff; unsigned int al=key7*key5 + key7 + key5; al=(al&0xff)-((al>>8)&0xff); if(al&0x100) al++; R=(R&0x00ffffffL) + (al<<24); } return R;}/* viaccess2 modification. Extracted from "Russian wafer" card. A lot of thanks to it's author :) */void cViaccess::Via2Mod(const unsigned char *key2, unsigned char *data){ int kb, db; for(db=7; db>=0; db--) { for(kb=7; kb>3; kb--) { int a0=kb^db; int pos=7; if(a0&4) { a0^=7; pos^=7; } a0=(a0^(kb&3)) + (kb&3); if(!(a0&4)) data[db]^=(key2[kb] ^ ((data[kb^pos]*key2[kb^4]) & 0xFF)); } } for(db=0; db<8; db++) { for(kb=0; kb<4; kb++) { int a0=kb^db; int pos=7; if(a0&4) { a0^=7; pos^=7; } a0=(a0^(kb&3)) + (kb&3); if(!(a0&4)) data[db]^=(key2[kb] ^ ((data[kb^pos]*key2[kb^4]) & 0xFF)); } }}void cViaccess::Decode(unsigned char *data, const unsigned char *key){ if(v2mode) Via2Mod(v2key,data); Des(data,key,VIA_DES); if(v2mode) Via2Mod(v2key,data);}void cViaccess::SetV2Mode(const unsigned char *key2){ if(key2) { memcpy(v2key,key2,sizeof(v2key)); v2mode=true; } else v2mode=false;}void cViaccess::SetHashKey(const unsigned char *key){ memcpy(hkey,key,sizeof(hkey));}void cViaccess::HashByte(unsigned char c){ hbuff[pH++]^=c; if(pH==8) { pH=0; Hash(); }}void cViaccess::HashClear(void){ memset(hbuff,0,sizeof(hbuff)); pH=0;}void cViaccess::Hash(void){ if(v2mode) Via2Mod(v2key,hbuff); Des(hbuff,hkey,VIA_DES_HASH); if(v2mode) Via2Mod(v2key,hbuff);}int cViaccess::HashNanos(const unsigned char *data, int len){ int i=0; pH=0; if(data[0]==0x9f) { HashByte(data[i++]); HashByte(data[i++]); for(int j=0; j<data[1]; j++) HashByte(data[i++]); while(pH!=0) HashByte(0); } for(; i<len; i++) HashByte(data[i]); return i;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -