2 Star 1 Fork 0

长江/oscam-nx111

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
reader-nagracak7.c 18.73 KB
一键复制 编辑 原始数据 按行查看 历史
gorgone 提交于 2020-11-12 20:09 +08:00 . nagra cleanup
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655
#include "globals.h"
#ifdef READER_NAGRA_MERLIN
#include "cscrypt/bn.h"
#include "cscrypt/idea.h"
#include "csctapi/icc_async.h"
#include "oscam-time.h"
#include "reader-common.h"
#include "reader-nagra-common.h"
#include "reader-nagracak7.h"
#include "oscam-work.h"
#include "cscrypt/des.h"
#include "cscrypt/mdc2.h"
static const uint8_t d00ff[] = { 0x00, 0xFF, 0xFF, 0xFF };
static uint8_t data1[] = { 0x00, 0x00, 0x00, 0x01 };
// Datatypes
#define SYSID_CAID 0x02
#define IRDINFO 0x03
#define DT05 0x05
#define TIERS 0x0C
static time_t tier_date(uint64_t date, char *buf, int32_t l)
{
time_t ut = +694224000L + (date >> 1);
if(buf)
{
struct tm t;
cs_gmtime_r(&ut, &t);
l = 27;
snprintf(buf, l, "%04d/%02d/%02d", t.tm_year + 1900, t.tm_mon + 1, t.tm_mday);
}
return ut;
}
void rsa_decrypt(uint8_t *edata50, int len, uint8_t *out, uint8_t *key, int keylen, uint8_t *expo, uint8_t expolen)
{
BN_CTX *ctx0 = BN_CTX_new();
#ifdef WITH_LIBCRYPTO
BN_CTX_start(ctx0);
#endif
BIGNUM *bnN0 = BN_CTX_get(ctx0);
BIGNUM *bnE0 = BN_CTX_get(ctx0);
BIGNUM *bnCT0 = BN_CTX_get(ctx0);
BIGNUM *bnPT0 = BN_CTX_get(ctx0);
BN_bin2bn(&key[0], keylen, bnN0);
BN_bin2bn(&expo[0], expolen, bnE0);
BN_bin2bn(&edata50[0], len, bnCT0);
BN_mod_exp(bnPT0, bnCT0, bnE0, bnN0, ctx0);
memset(out,0x00,len);
BN_bn2bin(bnPT0, out+ (len- BN_num_bytes(bnPT0)));
BN_CTX_end(ctx0);
BN_CTX_free(ctx0);
}
static void addProvider(struct s_reader *reader, uint8_t *cta_res)
{
uint8_t i;
bool toadd = true;
for(i = 0; i < reader->nprov; i++)
{
if((cta_res[19] == reader->prid[i][2]) && (cta_res[20] == reader->prid[i][3]))
{
toadd = false;
}
}
if(toadd)
{
reader->prid[reader->nprov][0] = 0;
reader->prid[reader->nprov][1] = 0;
reader->prid[reader->nprov][2] = cta_res[19];
reader->prid[reader->nprov][3] = cta_res[20];
memcpy(reader->sa[reader->nprov], reader->sa[0], 0x04);
reader->nprov += 1;
}
}
static int32_t ParseDataType(struct s_reader *reader, uint8_t dt, uint8_t *cta_res, uint16_t cta_lr)
{
char ds[36], de[36];
switch(dt)
{
case SYSID_CAID:
{
reader->prid[0][0] = 0x00;
reader->prid[0][1] = 0x00;
reader->prid[0][2] = cta_res[19];
reader->prid[0][3] = cta_res[20];
reader->prid[1][0] = 0x00;
reader->prid[1][1] = 0x00;
reader->prid[1][2] = 0x00;
reader->prid[1][3] = 0x00;
memcpy(reader->sa[1], reader->sa[0], 0x04);
reader->nprov += 1;
reader->caid = (SYSTEM_NAGRA | cta_res[25]);
rdr_log_dbg(reader, D_READER, "CAID : %04X", reader->caid);
return OK;
}
case IRDINFO: // case 0x03
{
if(cta_res[21] == 0x9C)
{
uint32_t timestamp = b2i(0x04, cta_res + 22);
reader->card_valid_to = tier_date(timestamp, de, 11);
rdr_log(reader, "Provider Sys ID: %02X %02X is active to: %s", cta_res[19], cta_res[20], de);
}
return OK;
}
case DT05: // case 0x05
{
IDEA_KEY_SCHEDULE ks;
memcpy(reader->edata,cta_res + 26, 0x70);
reader->dt5num = cta_res[20];
rsa_decrypt(reader->edata, 0x70, reader->out, reader->mod1, reader->mod1_length, reader->public_exponent, reader->public_exponent_length);
if(reader->dt5num == 0x00)
{
memcpy(reader->kdt05_00,&reader->out[18], 0x5C + 2);
memcpy(&reader->kdt05_00[0x5C + 2], cta_res + 26 + 0x70, 6);
memcpy(reader->ideakey1, reader->out, 16);
memcpy(reader->block3, cta_res + 26 + 0x70 + 6, 8);
idea_set_encrypt_key(reader->ideakey1, &ks);
memset(reader->v, 0, sizeof(reader->v));
idea_cbc_encrypt(reader->block3, reader->iout, 8, &ks, reader->v, IDEA_DECRYPT);
memcpy(&reader->kdt05_00[0x5C + 2 + 6],reader->iout, 8);
rdr_log_dump_dbg(reader, D_READER, reader->kdt05_00, sizeof(reader->kdt05_00), "DT05_00: ");
}
if(reader->dt5num == 0x10)
{
memcpy(reader->kdt05_10, &reader->out[16], 6 * 16);
memcpy(reader->ideakey1, reader->out, 16);
memcpy(reader->block3, cta_res + 26 + 0x70, 8);
idea_set_encrypt_key(reader->ideakey1, &ks);
memset(reader->v, 0, sizeof(reader->v));
idea_cbc_encrypt(reader->block3, reader->iout, 8, &ks, reader->v, IDEA_DECRYPT);
memcpy(&reader->kdt05_10[6 * 16],reader->iout,8);
rdr_log_dump_dbg(reader, D_READER, reader->kdt05_10, sizeof(reader->kdt05_10), "DT05_10: ");
}
return OK;
}
case TIERS: // case 0x0C
{
uint16_t chid;
if((cta_lr >= 0x30) && (chid = b2i(0x02, cta_res + 23)))
{
uint32_t id = b2i(0x02, cta_res + 19);
uint32_t start_date;
uint32_t expire_date1;
uint32_t expire_date2;
uint32_t expire_date;
switch(reader->caid)
{
case 0x1860: // HD03
start_date = b2i(0x04, cta_res + 42);
expire_date1 = b2i(0x04, cta_res + 28);
expire_date2 = b2i(0x04, cta_res + 46);
expire_date = expire_date1 <= expire_date2 ? expire_date1 : expire_date2;
break;
case 0x186A: // HD04, HD05
start_date = b2i(0x04, cta_res + 53);
expire_date1 = b2i(0x04, cta_res + 39);
expire_date2 = b2i(0x04, cta_res + 57);
expire_date = expire_date1 <= expire_date2 ? expire_date1 : expire_date2;
break;
default: // unknown card
start_date = 1;
expire_date = 0x569EFB7F;
}
cs_add_entitlement(reader,
reader->caid,
id,
chid,
0,
tier_date(start_date, ds, 11),
tier_date(expire_date, de, 11),
4,
1);
rdr_log(reader, "|%04X|%04X |%s |%s |", id, chid, ds, de);
addProvider(reader, cta_res);
}
return OK;
}
default:
return OK;
}
return ERROR;
}
static int32_t CAK7do_cmd(struct s_reader *reader, uint8_t dt, uint8_t len, uint8_t *res, uint16_t *rlen, int32_t sub, uint8_t retlen)
{
uint8_t dtdata[0x10];
memset(dtdata, 0xCC, len);
dtdata[7] = 0x04;
dtdata[8] = 0x04;
dtdata[9] = (sub >> 16) & 0xFF;
dtdata[10] = (sub >> 8) & 0xFF;
dtdata[11] = (sub) & 0xFF;
dtdata[12] = dt;
do_cak7_cmd(reader, res, rlen, dtdata, sizeof(dtdata), retlen);
return OK;
}
static int32_t CAK7GetDataType(struct s_reader *reader, uint8_t dt)
{
def_resp;
int32_t sub = 0x00;
uint8_t retlen = 0x10;
while(1)
{
CAK7do_cmd(reader, dt, 0x10, cta_res, &cta_lr, sub, retlen);
// hier eigentlich check auf 90 am ende usw... obs halt klarging ...
if((cta_lr == 0) || (cta_res[cta_lr-2] == 0x6F && cta_res[cta_lr-1] == 0x01))
{
reader->card_status = CARD_NEED_INIT;
add_job(reader->client, ACTION_READER_RESTART, NULL, 0);
break;
}
uint32_t newsub = (cta_res[9] << 16) + (cta_res[10] << 8) + (cta_res[11]);
if(newsub == 0xFFFFFF)
{
break;
}
if(cta_res[12] == dt)
{
uint8_t oretlen = retlen;
retlen = cta_res[13] + 0x10 + 0x2;
while(retlen % 0x10 != 0x00)
{
retlen++;
}
if(retlen == oretlen)
{
sub = newsub + 1;
retlen = 0x10;
ParseDataType(reader, dt, cta_res, cta_lr);
}
}
else
{
break;
}
}
return OK;
}
void CAK7_getCamKey(struct s_reader *reader)
{
def_resp;
uint8_t cmd0e[] = {0xCC,0xCC,0xCC,0xCC,0x00,0x00,0x09,0x0E,0x83,0x00,0x00,0x00,0x00,0x00,0x64,0x65,0x6D,0x6F,0x34,0x11,0x9D,
0x7E,0xEE,0xCE,0x53,0x09,0x80,0xAE,0x6B,0x5A,0xEE,0x3A,0x41,0xCE,0x09,0x75,0xEF,0xA6,0xBF,0x1E,0x98,0x4F,
0xA4,0x11,0x6F,0x43,0xCA,0xCD,0xD0,0x6E,0x69,0xFA,0x25,0xC1,0xF9,0x11,0x8E,0x7A,0xD0,0x19,0xC0,0xEB,0x00,
0xC0,0x57,0x2A,0x40,0xB7,0xFF,0x8A,0xBB,0x25,0x21,0xD7,0x50,0xE7,0x35,0xA1,0x85,0xCD,0xA6,0xD3,0xDE,0xB3,
0x3D,0x16,0xD4,0x94,0x76,0x8A,0x82,0x8C,0x70,0x25,0xD4,0x00,0xD0,0x64,0x8C,0x26,0xB9,0x5F,0x44,0xFF,0x73,
0x70,0xAB,0x43,0xF5,0x68,0xA2,0xB1,0xB5,0x8A,0x8E,0x02,0x5F,0x96,0x06,0xA8,0xC3,0x4F,0x15,0xCD,0x99,0xC2,
0x69,0xB8,0x35,0x68,0x11,0x4C,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0xCC,0xCC,0xCC,0xCC};
get_random_bytes(data1, 0x04);
if (data1[3] == 0xFF)
{
data1[3]--;
}
memcpy(cmd0e + 9, data1, 0x04);
data1[3]++;
if (reader->irdid_length == 4)
{
memcpy(&cmd0e[14], reader->irdid, reader->irdid_length); // inject irdid
}
// inject provid
cmd0e[18] = reader->prid[0][2];
cmd0e[19] = reader->prid[0][3];
if (reader->nuid_length == 4)
{
memcpy(&cmd0e[132], reader->nuid, reader->nuid_length); // inject NUID
}
do_cak7_cmd(reader,cta_res, &cta_lr, cmd0e, sizeof(cmd0e), 0x20);
reader->cak7_restart = (cta_res[22] << 16);
reader->cak7_restart += (cta_res[23] << 8);
reader->cak7_restart += (cta_res[24] );
reader->cak7_restart--;
memcpy(reader->cardid,cta_res + 14, 4);
rdr_log_dump_dbg(reader, D_READER, reader->cardid, 0x04, "CardSerial: ");
memcpy(reader->hexserial + 2, reader->cardid, 4);
memcpy(reader->sa[0], reader->cardid, 3);
memcpy(reader->sa[1], reader->sa[0], 4);
unsigned long datal = (cta_res[9] << 24) + (cta_res[10] << 16) + (cta_res[11] << 8) + (cta_res[12]);
datal++;
reader->data2[0] = (datal >> 24) & 0xFF;
reader->data2[1] = (datal >> 16) & 0xFF;
reader->data2[2] = (datal >> 8) & 0xFF;
reader->data2[3] = (datal ) & 0xFF;
rsa_decrypt(reader->data50, reader->data50_length, reader->data, reader->mod50, reader->mod50_length, reader->public_exponent, reader->public_exponent_length);
memcpy(&reader->step1[0], d00ff, 4);
memcpy(&reader->step1[4], reader->data, 0x50);
memcpy(&reader->step1[4 + 0x50], reader->irdid, reader->irdid_length);
memcpy(&reader->step1[4 + 4 + 0x50], data1, 0x04);
memcpy(&reader->step1[4 + 4 + 4 + 0x50], reader->data2, 0x04);
rsa_decrypt(reader->step1, 0x60, reader->data, reader->key60, reader->key60_length, reader->exp60, reader->exp60_length);
memcpy(&reader->step2[0], d00ff, 4);
memcpy(&reader->step2[4], reader->cardid, 4);
memcpy(&reader->step2[8], reader->data, 0x60);
rsa_decrypt(reader->step2, 0x68, reader->data, reader->kdt05_10, 0x68, reader->public_exponent, reader->public_exponent_length);
memcpy(&reader->step3[0], d00ff, 4);
memcpy(&reader->step3[4], reader->data, 0x68);
rsa_decrypt(reader->step3, 0x6c, reader->data, reader->kdt05_00, 0x6c, reader->public_exponent, reader->public_exponent_length);
uint8_t cmd03[] = {0xCC,0xCC,0xCC,0xCC,0x00,0x00,0x0A,0x03,0x6C,
0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,
0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,
0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,
0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,
0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,
0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,
0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,
0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC};
memcpy(&cmd03[9],reader->data,0x6c);
do_cak7_cmd(reader,cta_res,&cta_lr,cmd03,sizeof(cmd03),0x90);
memcpy(reader->encrypted,&cta_res[10],0x68);
rsa_decrypt(reader->encrypted, 0x68, reader->result, reader->kdt05_10, 0x68, reader->public_exponent, reader->public_exponent_length);
memcpy(reader->stillencrypted,&reader->result[12],0x50);
rsa_decrypt(reader->stillencrypted, 0x50, reader->resultrsa, reader->mod50, reader->mod50_length, reader->public_exponent, reader->public_exponent_length);
uint8_t mdc_hash[MDC2_DIGEST_LENGTH];
memset(mdc_hash,0x00,MDC2_DIGEST_LENGTH);
MDC2_CTX c;
MDC2_Init(&c);
MDC2_Update(&c, reader->resultrsa, sizeof(reader->resultrsa));
MDC2_Final(&(mdc_hash[0]), &c);
memcpy(&reader->cak7_aes_key[16],mdc_hash,16);
memcpy(reader->cak7_aes_key,mdc_hash,16);
}
void CAK7_reinit(struct s_reader *reader)
{
ATR newatr[ATR_MAX_SIZE];
memset(newatr, 0, 1);
if(ICC_Async_Activate(reader, newatr, 0))
{
reader->card_status = CARD_NEED_INIT;
add_job(reader->client, ACTION_READER_RESTART, NULL, 0);
}
else
{
reader->cak7_seq = 0;
CAK7_getCamKey(reader);
}
}
static int32_t nagra3_card_init(struct s_reader *reader, ATR *newatr)
{
get_atr;
memset(reader->hexserial, 0x00, 0x08);
reader->public_exponent[0] = 0x01;
reader->public_exponent[1] = 0x00;
reader->public_exponent[2] = 0x01;
reader->public_exponent_length = 3;
reader->irdid[0] = 0x64;
reader->irdid[1] = 0x65;
reader->irdid[2] = 0x6D;
reader->irdid[3] = 0x6F;
reader->irdid_length = 4;
reader->cak7_seq = 0;
cs_clear_entitlement(reader);
if(memcmp(atr + 11, "DNASP4", 6) == 0)
{
memcpy(reader->rom, atr + 11, 15);
rdr_log(reader,"Rom revision: %.15s", reader->rom);
}
else
{
return ERROR;
}
// check the completeness of the required CAK7 keys
if(reader->mod1_length && reader->irdid_length && reader->data50_length && reader->mod50_length && reader->key60_length && reader->exp60_length && reader->nuid_length)
{
rdr_log_dbg(reader, D_READER, "All parameters for CAK7 global pairing are set.");
}
else
{
rdr_log(reader, "ERROR: Not all required CAK7 parameters are set!");
reader->card_status = CARD_FAILURE;
return ERROR;
}
reader->nprov = 1;
CAK7GetDataType(reader, DT05);
CAK7GetDataType(reader, SYSID_CAID); // sysid+caid
CAK7_getCamKey(reader);
rdr_log(reader, "ready for requests");
return OK;
}
static int32_t nagra3_card_info(struct s_reader *reader)
{
char tmp[4 * 3 + 1];
rdr_log(reader, "ROM: %c %c %c %c %c %c %c %c", reader->rom[0], reader->rom[1], reader->rom[2], reader->rom[3], reader->rom[4], reader->rom[5], reader->rom[6], reader->rom[7]);
rdr_log(reader, "REV: %c %c %c %c %c %c", reader->rom[9], reader->rom[10], reader->rom[11], reader->rom[12], reader->rom[13], reader->rom[14]);
rdr_log_sensitive(reader, "SER: {%s}", cs_hexdump(1, reader->hexserial + 2, 4, tmp, sizeof(tmp)));
rdr_log(reader, "CAID: %04X", reader->caid);
rdr_log(reader, "Prv.ID: %s(sysid)", cs_hexdump(1, reader->prid[0], 4, tmp, sizeof(tmp)));
CAK7GetDataType(reader, IRDINFO);
cs_clear_entitlement(reader); // reset the entitlements
rdr_log(reader, "-----------------------------------------");
rdr_log(reader, "|id |tier |valid from |valid to |");
rdr_log(reader, "+----+--------+------------+------------+");
CAK7GetDataType(reader, TIERS);
rdr_log(reader, "-----------------------------------------");
uint8_t i;
for(i = 1; i < reader->nprov; i++)
{
rdr_log(reader, "Prv.ID: %s", cs_hexdump(1, reader->prid[i], 4, tmp, sizeof(tmp)));
}
struct timeb now;
cs_ftime(&now);
reader->last_refresh=now;
return OK;
}
static void nagra3_post_process(struct s_reader *reader)
{
if(reader->cak7_seq >= reader->cak7_restart)
{
rdr_log(reader, "reinit necessary to reset command counter");
CAK7_reinit(reader);
}
else if((reader->cak7_camstate & 64) == 64)
{
rdr_log_dbg(reader, D_READER, "renew Session Key: CAK7");
add_job(reader->client, ACTION_READER_RENEW_SK, NULL, 0); //CAK7_getCamKey
}
}
static int32_t nagra3_do_ecm(struct s_reader *reader, const ECM_REQUEST *er, struct s_ecm_answer *ea)
{
def_resp;
uint8_t ecmreq[0xC0];
memset(ecmreq,0xCC,0xC0);
ecmreq[ 7] = 0x05;
ecmreq[ 8] = 0x8A;
ecmreq[ 9] = 0x00;
ecmreq[10] = 0x00;
ecmreq[11] = 0x00;
ecmreq[12] = 0x00;
ecmreq[13] = 0x01;
memcpy(&ecmreq[14], er->ecm + 4, er->ecm[4] + 1);
do_cak7_cmd(reader, cta_res, &cta_lr, ecmreq, sizeof(ecmreq), 0xB0);
if(cta_res[cta_lr - 2] != 0x90 && cta_res[cta_lr - 1] != 0x00)
{
rdr_log(reader, "(ECM) Reader will be restart now cause: %02X %02X card answer!!!", cta_res[cta_lr - 2], cta_res[cta_lr - 1]);
reader->card_status = CARD_NEED_INIT;
add_job(reader->client, ACTION_READER_RESTART, NULL, 0);
}
if(cta_res[27] == 0x5C)
{
uint8_t _cwe0[8];
uint8_t _cwe1[8];
if(cta_res[78] == 0x01)
{
rdr_log (reader,"Swap dcw is at use !");
memcpy(_cwe0,&cta_res[52], 0x08);
memcpy(_cwe1,&cta_res[28], 0x08);
}
else
{
memcpy(_cwe0,&cta_res[28], 0x08);
memcpy(_cwe1,&cta_res[52], 0x08);
}
if(!reader->cwekey_length)
{
rdr_log_dbg(reader, D_READER, "ERROR: CWPK is not set, can not decrypt CW");
return ERROR;
}
des_ecb3_decrypt(_cwe0, reader->cwekey);
des_ecb3_decrypt(_cwe1, reader->cwekey);
int chkok = 1;
if(((_cwe0[0] + _cwe0[1] + _cwe0[2]) & 0xFF) != _cwe0[3])
{
chkok = 0;
rdr_log_dbg(reader, D_READER, "CW0 checksum error [0]");
}
if(((_cwe0[4] + _cwe0[5] + _cwe0[6]) & 0xFF) != _cwe0[7])
{
chkok = 0;
rdr_log_dbg(reader, D_READER, "CW0 checksum error [1]");
}
if(((_cwe1[0] + _cwe1[1] + _cwe1[2]) & 0xFF) != _cwe1[3])
{
chkok = 0;
rdr_log_dbg(reader, D_READER, "CW1 checksum error [0]");
}
if(((_cwe1[4] + _cwe1[5] + _cwe1[6]) & 0xFF) != _cwe1[7])
{
chkok = 0;
rdr_log_dbg(reader, D_READER, "CW1 checksum error [1]");
}
reader->cak7_camstate = cta_res[4];
if(chkok == 1)
{
rdr_log_dbg(reader, D_READER, "CW Decrypt ok");
memcpy(ea->cw, _cwe0, 0x08);
memcpy(ea->cw + 8, _cwe1, 0x08);
return OK;
}
}
return ERROR;
}
static int32_t nagra3_do_emm(struct s_reader *reader, EMM_PACKET *ep)
{
def_resp;
uint8_t emmreq[0xC0];
memset(emmreq, 0xCC, 0xC0);
emmreq[ 7] = 0x05;
emmreq[ 8] = 0x8A;
emmreq[ 9] = 0x00;
emmreq[10] = 0x00;
emmreq[11] = 0x00;
emmreq[12] = 0x00;
emmreq[13] = 0x01;
memcpy(&emmreq[14], ep->emm + 9, ep->emm[9] + 1);
do_cak7_cmd(reader, cta_res, &cta_lr, emmreq, sizeof(emmreq), 0xB0);
if(cta_lr == 0)
{
rdr_log_dbg(reader, D_READER, "card reinit necessary");
CAK7_reinit(reader);
}
else if(cta_res[cta_lr - 2] != 0x90 && cta_res[cta_lr - 1] != 0x00)
{
rdr_log(reader, "(EMM) Reader will be restart now cause: %02X %02X card answer!!!", cta_res[cta_lr - 2], cta_res[cta_lr - 1]);
CAK7_reinit(reader);
}
else
{
if(reader->cak7_seq >= reader->cak7_restart)
{
rdr_log_dbg(reader, D_READER, "reinit necessary to reset command counter");
CAK7_reinit(reader);
}
else if(cta_res[4] == 0x80)
{
rdr_log_dbg(reader, D_READER, "EMM forced card to reinit");
reader->card_status = CARD_NEED_INIT;
add_job(reader->client, ACTION_READER_RESTART, NULL, 0);
return OK;
}
else if(cta_res[13] == 0x02)
{
rdr_log_dbg(reader, D_READER, "Revision update - card reinit necessary");
reader->card_status = CARD_NEED_INIT;
add_job(reader->client, ACTION_READER_RESTART, NULL, 0);
return OK;
}
else if((cta_res[4] & 64) == 64)
{
rdr_log_dbg(reader, D_READER, "negotiating new Session Key");
CAK7_getCamKey(reader);
}
else if(cta_res[8] == 0x0E)
{
rdr_log_dbg(reader, D_READER, "card got wrong EMM");
return OK;
}
struct timeb now;
cs_ftime(&now);
int64_t gone_now = comp_timeb(&now, &reader->emm_last);
int64_t gone_refresh = comp_timeb(&reader->emm_last, &reader->last_refresh);
if(((gone_now > (int64_t)3600*1000) && (gone_now < (int64_t)365*24*3600*1000)) || ((gone_refresh > (int64_t)12*3600*1000) && (gone_refresh < (int64_t)365*24*3600*1000)))
{
reader->last_refresh=now;
add_job(reader->client, ACTION_READER_CARDINFO, NULL, 0); // refresh entitlement since it might have been changed!
}
}
return OK;
}
const struct s_cardsystem reader_nagracak7 =
{
.desc = "nagra merlin",
.caids = (uint16_t[]){ 0x18, 0 },
.do_emm = nagra3_do_emm,
.do_ecm = nagra3_do_ecm,
.post_process = nagra3_post_process,
.card_info = nagra3_card_info,
.card_init = nagra3_card_init,
.get_emm_type = nagra_get_emm_type,
.get_emm_filter = nagra_get_emm_filter,
};
#endif
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/4a02/oscam-nx111.git
git@gitee.com:4a02/oscam-nx111.git
4a02
oscam-nx111
oscam-nx111
master

搜索帮助