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

📄 viaccess.cpp

📁 DVB-S的softcam源代码
💻 CPP
📖 第 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 "stdafx.h"

#include <string.h>
#include "regex.h"

#include "common.h"
#include "sc.h"
#include "system.h"
#include "system-common.h"
#include "data.h"
#include "misc.h"
#include "crypto.h"
#include "parse.h"
#include "network.h"
#include "opts.h"
#include "win32lacks.h"

#define SYSTEM_VIACCESS      0x0500

#define SYSTEM_NAME          "Viaccess"
#define SYSTEM_PRI           -10
#define SYSTEM_CAN_HANDLE(x) ((x)==SYSTEM_VIACCESS)

static char AESKeyHost[30]="213.251.166.40";
static int AESKeyPort=80;
static char AESKeyPath[30]="~aes/aes/";

//#define DEBUG_LOG

#ifdef DEBUG_LOG
#define dl(x) { (x); }
#else
#define dl(x) ; 
#endif

// -- cPlainKeyVia -------------------------------------------------------------

#define VIA1_KEYLEN 8
#define VIA2_KEYLEN 16
#define VIATPS_KEYLEN 16

class 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);
};

static cPlainKeyTypeReg<cPlainKeyVia,'V',false> 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::Parse(const char *line)
{
	unsigned char sid[3], skeynr, skey[VIA2_KEYLEN];
#ifdef DEBUG
	const char *sline=line;
#endif
	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,"TPS",3)) {
			line+=3;
			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) {
			SetKey(skey,len);
			return true;
		}
	}
	d(printf("plainkeyvia: bad key format '%s'\n",sline))
	return false;
}

cString cPlainKeyVia::PrintKeyNr(void)
{
	return cString::sprintf((keynr==MBC3('T','P','S'))?"TPS":"%02X",keynr);
}

// -- cViaccessCardInfo --------------------------------------------------------

class cViaccessCardInfo : public cSimpleItem {
public:
	unsigned char ID[3], UA[5], SA[4], KEYNO[1], 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,ID,sizeof(ID)) && 
			GetHex(line,UA,sizeof(UA)) &&
			GetHex(line,SA,sizeof(SA)) &&
			GetHex(line,KEYNO,sizeof(KEYNO)) && 
			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;
}

bool cViaccess::Decrypt(const unsigned char *work_key, const unsigned char *data, int len, unsigned char *des_data1, unsigned char *des_data2)
{
	int pos=0, encStart=0;
	unsigned char signatur[8];
	while(pos<len) {
		switch(data[pos]) {
		case 0xea:                 // encrypted bytes
			encStart = pos + 2;
			memcpy(des_data1,&data[pos+2],8);
			memcpy(des_data2,&data[pos+2+8],8);
			break;
		case 0xf0:                 // signature
			memcpy(signatur,&data[pos+2],8);
			break;
		}
		pos += data[pos+1]+2;
    }
	HashClear();
	SetHashKey(work_key);
	// key preparation

⌨️ 快捷键说明

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