📄 irdeto.c
字号:
}
}
static bool IrdetoCheckStatus(U8* PB)
{
int i;
for(i=0;i<17;i++)
{
if(PB[0]==IrdetoStatusMsgs[i].uPBWords[0] && \
(PB[1]==IrdetoStatusMsgs[i].uPBWords[1] || IrdetoStatusMsgs[i].uPBWords[1]==0xFF))
return IrdetoStatusMsgs[i].bResult;
}
return false;
}
static U8 GetXorSum(const U8 *mem, int len)
{
U8 cs=0;
while(len>0) { cs ^= *mem++; len--; }
return cs;
}
#define XOR_START 0x3F /* Start value for xor checksum */
static int IrdetoWrite(Smart_Handle_t Handle,U8* cmd,U8* Response,U16 goodSB,U8* Status)
{
U16 len;
int r;
U16 Read =0;
Smart_ErrorCode_t error;
int iRetries;
len = cmd[5]+6;
cmd[len] = GetXorSum(cmd,len)^XOR_START;
len += 1;
r = 0;
iRetries = 3;
do
{
error = Smart_Transfer(Handle,cmd,len,Response,0,&Read,Status);
} while((Response[0] != 0x01)&&((--iRetries)>0));
if(error==SMC_NO_ERROR)
{
len = 4;
if(Response[0]==cmd[0] && Response[1]==cmd[1])
{
if(Status)
{
Status[0] = Response[2];
Status[1] = Response[3];
}
if((Response[2]*256+Response[3])==goodSB)
{
len += 5;
if(Response[7])
{
len += Response[7];
if(GetXorSum(Response,len)==XOR_START)
r = len;
}
else
{
r = len;
}
}
}
else
{
if(Status)
{
Status[0] = Response[1];
Status[1] = Response[2];
}
r = 3;
}
}
else
{
printf("IrdetoWrite Error: %x========= \n", error);
}
return r;
}
static bool IrdetoDecode(Smart_Handle_t Handle,U8* data,U8* cw)
{
int len;
U8 cmd[255]={0};
U8 ucIrdStatus[2];
U8 Response[100];
len = data[2]-3;
memcpy(cmd,ecmCmd,sizeof(ecmCmd));
cmd[5] = len;
memcpy(cmd+6,&data[6],len);
len=IrdetoWrite(Handle,cmd,Response,0x9D00,ucIrdStatus);
if(len>0)
{
if(IrdetoCheckStatus(ucIrdStatus) && (len>=23))
{
if(Response[6]==0x02)
{
RevCamCrypt(camKey,&Response[14]);
RevCamCrypt(camKey,&Response[22]);
memcpy(cw,&Response[14],8);
memcpy(cw+8,&Response[22],8);
}
return true;
}
}
return false;
}
static void SetProviderIrdeto(U8 pb, const U8 *pi,int iNum)
{
if(iNum>=11) return;
if((pi[0]==0x00)&&(pi[1]==0x00))
{
pstIrdetoInfo->aucProvId[iNum][0] = 0xFF;
pstIrdetoInfo->aucProvId[iNum][1] = 0xFF;
pstIrdetoInfo->aucProvId[iNum][2] = 0xFF;
pstIrdetoInfo->aucProvBase[iNum] = 0xFF;
}
else if((pi[0]==0xFF)&&(pi[1]==0xFF))
{
pstIrdetoInfo->aucProvId[iNum][0] = 0xFF;
pstIrdetoInfo->aucProvId[iNum][1] = 0xFF;
pstIrdetoInfo->aucProvId[iNum][2] = 0xFF;
pstIrdetoInfo->aucProvBase[iNum] = 0xFF;
}
else
{
pstIrdetoInfo->aucProvBase[iNum]=pb;
memcpy(pstIrdetoInfo->aucProvId[iNum],pi,3);
}
}
static void RotateLeft8Byte(U8 *key)
{
U8 t1=key[7];
int k;
for(k=0 ; k<8 ; k++)
{
U8 t2=t1>>7;
t1=key[k]; key[k]=(t1<<1) | t2;
}
}
static void RevCamCrypt(const U8 *key, U8 *data)
{
U8 localKey[8];
int idx1,idx2;
memcpy(localKey,key,sizeof(localKey));
for(idx1=0 ; idx1<8 ; idx1++)
{
for(idx2=0 ; idx2<8 ; idx2++)
{
const U8 tmp1=cryptTable[data[7] ^ localKey[idx2] ^ idx1];
const U8 tmp2=data[0];
data[0]=data[1];
data[1]=data[2];
data[2]=data[3];
data[3]=data[4];
data[4]=data[5];
data[5]=data[6] ^ tmp1;
data[6]=data[7];
data[7]=tmp1 ^ tmp2 ;
}
RotateLeft8Byte(localKey);
}
}
bool irdeto_parse_ecm(Smart_Handle_t Handle,U8* pbuf,U8* pucCW)
{
U8 cw[16];
if(IrdetoDecode(Handle,pbuf,cw))
{
cw[3] = cw[0]+cw[1]+cw[2];
cw[7] = cw[4]+cw[5]+cw[6];
cw[11] = cw[8]+cw[9]+cw[10];
cw[15] = cw[12]+cw[13]+cw[14];
memcpy(pucCW,cw,16);
return true;
}else
{
printf("Irdeto Ecm Error : IrdetoDecode failed !!\n");
}
return false;
}
unsigned int AddrLen(const U8 *data)
{
return data[3] & 0x07;
}
unsigned int AddrBase(const U8 *data)
{
return data[3] >> 3;
}
bool irdeto_parse_emm(Smart_Handle_t Handle,U8* buf,int length)
{
int i,len,mod,r;
bool accept,bIsHexSerial,bIsProviderUp;
U8 aucEmmCmd[255];
U8 ucIrdetoStatus[2];
U8 Response[255];
/* Calculate which mode will be used */
len = buf[0]&0x07;
mod = buf[0]>>3;
accept = false;
bIsHexSerial = false;
bIsProviderUp = false;
/* Check EMM Authorize */
if(mod&0x10)
{
/* Hex Address Case */
if(mod==pstIrdetoInfo->ucHexBase && (!len || !memcmp(&buf[1],pstIrdetoInfo->ucHexSerial,3)))
{
accept = true;
bIsHexSerial = true;
}
else
{
printf("mod !=pstIrdetoInfo->ucHexBase %02x: %02x ? \n", mod, pstIrdetoInfo->ucHexBase);
printf("buf %02x %02x %02x \n", buf[1],buf[2],buf[3]);
printf("pstIrdetoInfo->ucHexSerial %02x %02x %02x \n", pstIrdetoInfo->ucHexSerial[1],\
pstIrdetoInfo->ucHexSerial[2],\
pstIrdetoInfo->ucHexSerial[3]);
}
}
else
{
/* Provider Address Case */
for(i=0;i<pstIrdetoInfo->ucNoOfProv;i++)
{
#if 0
if((!len || !memcmp(&buf[1],pstIrdetoInfo->aucProvId[i],2))) /* Not 3 !! */
#else
if(len != 0||!memcmp(&buf[1],pstIrdetoInfo->aucProvId[i],2)||buf[2]==0)
#endif
{
accept = true;
bIsProviderUp = true;
break;
}
}
}
/* if accept,send emm to card */
if(accept)
{
len++;
memset(aucEmmCmd,0,sizeof(aucEmmCmd));
memcpy(aucEmmCmd,emmCmd,sizeof(emmCmd));
/* HEX Processing */
if(mod&0x10)
{
aucEmmCmd[5] = length-1;
memcpy(aucEmmCmd+6,buf,4);
memcpy(aucEmmCmd+10,buf+6,length-5);
}
else
{
aucEmmCmd[5] = length-1;
if(len==3)
{
memcpy(aucEmmCmd+6,buf,4);
memcpy(aucEmmCmd+10,buf+5,aucEmmCmd[5]-3);
}
else
{
memcpy(aucEmmCmd+6,buf,4);
memcpy(aucEmmCmd+10,buf+6,aucEmmCmd[5]-4);
}
/* Adjust length filed, Very important !! */
if(len==3)
aucEmmCmd[5]++;
}
/* Send Cmd to Card */
r=IrdetoWrite(Handle,aucEmmCmd,Response,0,ucIrdetoStatus);
if((r>0 )&& IrdetoCheckStatus(ucIrdetoStatus))
{
if(bIsHexSerial)
{
IrdetoRefreshProvInfo(Handle,true);
}
if(bIsProviderUp)
{
IrdetoRefreshProvInfo(Handle,false);
}
return true;
}
else
{
printf("Error r= %d , bIsHexSerial = %d, bIsProviderUp = %d", r, bIsHexSerial, bIsProviderUp);
printf("pstIrdetoInfo->aucProvId = %02x %02x %02x", buf[1],buf[2],buf[3]);
printf("pstIrdetoInfo->aucProvId = %02x %02x %02x", pstIrdetoInfo->aucProvId[i][0],\
pstIrdetoInfo->aucProvId[i][1],pstIrdetoInfo->aucProvId[i][2]);
}
}
else
{
printf("======not accept!!!\n");
}
return false;
}
////////////////----The end ----------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -