|
SASC
DVBSoftCAM
|
Inheritance diagram for cSmartCardViaccess:Public Member Functions | |
| cSmartCardViaccess (void) | |
| virtual bool | Init (void) |
| virtual bool | Decode (const cEcmInfo *ecm, const unsigned char *data, unsigned char *cw) |
| virtual bool | Update (int pid, int caid, const unsigned char *data) |
| cSmartCardViaccess (void) | |
| virtual bool | Init (void) |
| virtual bool | Decode (const cEcmInfo *ecm, const unsigned char *data, unsigned char *cw) |
| virtual bool | Update (int pid, int caid, const unsigned char *data) |
Definition at line 201 of file sc-viaccess.c.
| cSmartCardViaccess::cSmartCardViaccess | ( | void | ) |
Definition at line 227 of file sc-viaccess.c.
:cSmartCard(&cardCfg,msgs) { memset(lastId,0,sizeof(lastId)); }
| cSmartCardViaccess::cSmartCardViaccess | ( | void | ) |
| bool cSmartCardViaccess::Decode | ( | const cEcmInfo * | ecm, |
| const unsigned char * | data, | ||
| unsigned char * | cw | ||
| ) | [virtual] |
Implements cSmartCard.
Definition at line 386 of file sc-viaccess.c.
References AUTOMEM, data, cAES::Decrypt(), cProviders::FindProv(), cSmartCard::IsoRead(), cSmartCard::IsoWrite(), cParseViaccess::KeyNr(), L_SC_ERROR, MAX_LEN, cParseViaccess::PayloadStart(), PRINTF, cParseViaccess::ProvIdPtr(), SCT_LEN, start(), and cSmartCard::Status().
{
static unsigned char ins88[] = { 0xca,0x88,0x00,0x00,0x00 }; // set ecm
static unsigned char insf8[] = { 0xca,0xf8,0x00,0x00,0x00 }; // set geographic info
static unsigned char insc0[] = { 0xca,0xc0,0x00,0x00,0x12 }; // read dcw
cProviderScViaccess *p=(cProviderScViaccess *)FindProv(data);
if(p) {
unsigned char keynr=cParseViaccess::KeyNr(data);
if(CheckKey(p,keynr)) {
if(!SetProvider(cParseViaccess::ProvIdPtr(data))) return false;
const unsigned char *start=cParseViaccess::PayloadStart(data);
bool hasD2=false;
if(start[0]==0xD2) { // TPS alike, TNTSAT/TNTop
start+=start[1]+2;
hasD2=true;
}
start+=5;
const unsigned char *DE04=0;
if(start[0]==0xDE && start[1]==0x04) {
DE04=start;
start+=6;
}
const unsigned char *ecm88Data=start;
int ecm88Len=SCT_LEN(data)-(start-data);
int ecmf8Len=0;
while(ecm88Len>0 && ecm88Data[0]<0xA0) {
const int nanoLen=ecm88Data[1]+2;
ecmf8Len+=nanoLen;
ecm88Len-=nanoLen; ecm88Data+=nanoLen;
}
if(ecmf8Len) {
insf8[3]=keynr;
insf8[4]=ecmf8Len;
if(!IsoWrite(insf8,start) || !Status()) return false;
}
ins88[2]=ecmf8Len?1:0;
ins88[3]=keynr;
ins88[4]=ecm88Len;
if(DE04) {
unsigned char *mem=AUTOMEM(ecm88Len+6);
memcpy(mem,DE04,6);
memcpy(mem+6,ecm88Data,ecm88Len);
ins88[4]+=6;
ecm88Data=mem;
}
if(!IsoWrite(ins88,ecm88Data) || !Status()) return false; // request dcw
unsigned char buff[MAX_LEN];
if(!IsoRead(insc0,buff) || !Status()) return false; // read dcw
unsigned char cwbuff[16];
int cwmask=0;
switch(buff[0]) {
case 0xe8: // even
if(buff[1]==8) { memcpy(cwbuff,buff+2,8); cwmask=1; }
break;
case 0xe9: // odd
if(buff[1]==8) { memcpy(cwbuff+8,buff+2,8); cwmask=2; }
break;
case 0xea: // complete
if(buff[1]==16) { memcpy(cwbuff,buff+2,16); cwmask=3; }
break;
}
if(cwmask) {
if(hasD2 && !Decrypt(cwbuff,16))
PRINTF(L_SC_ERROR,"no AES key for this card");
if(cwmask&1) memcpy(cw,cwbuff,8);
if(cwmask&2) memcpy(cw+8,cwbuff+8,8);
return true;
}
}
else PRINTF(L_SC_ERROR,"key not found on card");
}
else PRINTF(L_SC_ERROR,"provider not found on card");
return false;
}
| virtual bool cSmartCardViaccess::Decode | ( | const cEcmInfo * | ecm, |
| const unsigned char * | data, | ||
| unsigned char * | cw | ||
| ) | [virtual] |
Implements cSmartCard.
| bool cSmartCardViaccess::Init | ( | void | ) | [virtual] |
Implements cSmartCard.
Definition at line 233 of file sc-viaccess.c.
References cProviders::AddProv(), cSmartCardDataViaccess::aes, cSmartCard::atr, cProviderScViaccess::availKeys, cInfoStr::Begin(), Bin2Int, Bin2LongLong(), disableParental, dtAES, dtPIN, cSmartCards::FindCardData(), cInfoStr::Finish(), Atr::hist, Atr::histLen, cSmartCard::idStr, cSmartCard::infoStr, cSmartCard::IsoRead(), cSmartCard::IsoWrite(), L_SC_ERROR, L_SC_INIT, MAX_LEN, cProviderScViaccess::name, cSmartCardDataViaccess::pin, cLineBuff::Printf(), PRINTF, cProviderViaccess::ProvId(), cIdSet::ResetIdSet(), SC_NAME, cIdSet::SetCard(), cAES::SetKey(), smartcards, cSmartCard::Status(), cLineBuff::Strcat(), and Atr::T.
{
static const unsigned char verifyBytes[] = { 0x90,0x00 };
if(atr->T!=0 || atr->histLen<7 || memcmp(&atr->hist[5],verifyBytes,sizeof(verifyBytes))) {
PRINTF(L_SC_INIT,"doesn't look like a Viaccess card");
return false;
}
infoStr.Begin();
infoStr.Strcat("Viaccess smartcard\n");
const char *ver=0;
switch((atr->hist[3]<<8)|atr->hist[4]) {
case 0x6268: ver="2.3"; break;
case 0x6468:
case 0x6668: ver="2.4"; break;
case 0xa268: ver="2.5"; break;
case 0xc168: ver="2.6"; break;
default: ver="unknown"; break;
}
PRINTF(L_SC_INIT,"card v.%s",ver);
snprintf(idStr,sizeof(idStr),"%s (V.%s)",SC_NAME,ver);
static unsigned char insac[] = { 0xca, 0xac, 0x00, 0x00, 0x00 }; // select data
static unsigned char insb8[] = { 0xca, 0xb8, 0x00, 0x00, 0x00 }; // read selected data
static unsigned char insa4[] = { 0xca, 0xa4, 0x00, 0x00, 0x00 }; // select issuer
static unsigned char insc0[] = { 0xca, 0xc0, 0x00, 0x00, 0x00 }; // read data item
unsigned char buff[MAX_LEN];
ResetIdSet();
insac[2]=0xa4; // request unique id
if(!IsoWrite(insac,buff) || !Status()) {
PRINTF(L_SC_ERROR,"failed to request ua");
return false;
}
insb8[4]=0x07; // read unique id
if(!IsoRead(insb8,buff) || !Status() || buff[1]!=0x05) {
PRINTF(L_SC_ERROR,"failed to read ua");
return false;
}
memcpy(ua,&buff[2],sizeof(ua));
SetCard(new cCardViaccess(ua));
PRINTF(L_SC_INIT,"card UA: %llu",Bin2LongLong(ua,5));
infoStr.Printf("Card v.%s UA %010llu\n",ver,Bin2LongLong(ua,5));
insa4[2]=0x00; // select issuer 0
if(!IsoWrite(insa4,buff) || !Status()) {
PRINTF(L_SC_ERROR,"failed to select issuer 0");
return false;
}
int issuer=0;
do {
insc0[4]=0x1a; // show provider properties
if(!IsoRead(insc0,buff) || !Status()) {
PRINTF(L_SC_ERROR,"failed to read prov properties");
return false;
}
unsigned char buff2[MAX_LEN];
insac[2]=0xa5; // request sa
if(!IsoWrite(insac,buff2) || !Status()) {
PRINTF(L_SC_ERROR,"failed to request sa");
return false;
}
insb8[4]=0x06; // read sa
if(!IsoRead(insb8,buff2) || !Status()) {
PRINTF(L_SC_ERROR,"failed to read sa");
return false;
}
if(issuer==0) memcpy(sa0,&buff[2],sizeof(sa0));
cProviderScViaccess *p=new cProviderScViaccess(&buff[0],&buff2[2]);
if(p) {
AddProv(p);
memcpy(p->availKeys,buff+10,sizeof(p->availKeys));
insac[2]=0xa7; // request name
if(!IsoWrite(insac,buff) || !Status()) {
PRINTF(L_SC_ERROR,"failed to request prov name");
return false;
}
insb8[4]=0x02; // read name nano + len
if(!IsoRead(insb8,buff) || !Status()) {
PRINTF(L_SC_ERROR,"failed to read prov name length");
return false;
}
unsigned int nameLen=buff[1];
if(nameLen>=sizeof(p->name)) {
PRINTF(L_SC_ERROR,"provider name buffer overflow");
nameLen=sizeof(p->name)-1;
}
insb8[4]=nameLen;
if(!IsoRead(insb8,buff) || !Status()) {
PRINTF(L_SC_ERROR,"failed to read prov name");
return false;
}
memcpy(p->name,buff,nameLen); p->name[nameLen]=0;
PRINTF(L_SC_INIT,"provider %06x (%s)",(int)p->ProvId(),p->name);
infoStr.Printf("Prov %06x (%s) SA %08u\n",(int)p->ProvId(),p->name,Bin2Int(&buff2[2],4));
}
else PRINTF(L_SC_ERROR,"no memory for provider");
insa4[2]=0x02; // next issuer
if(!IsoWrite(insa4,buff) || !Status()) {
PRINTF(L_SC_ERROR,"failed to select next issuer");
return false;
}
issuer++;
} while(GetSW1()==0x00);
infoStr.Finish();
if(disableParental) {
static unsigned char ins24[] = { 0xca,0x24,0x02,0x00,0x09 };
static unsigned char pindt[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F };
cSmartCardDataViaccess cd(dtPIN,ua);
cSmartCardDataViaccess *entry=(cSmartCardDataViaccess *)smartcards.FindCardData(&cd);
if(entry) {
PRINTF(L_SC_INIT,"got PIN from smartcard.conf.");
memcpy(&pindt[0],entry->pin,8);
if(!IsoWrite(ins24,pindt) || !Status())
PRINTF(L_SC_ERROR,"failed to disable parental lock");
}
else PRINTF(L_SC_INIT,"no PIN available.");
}
cSmartCardDataViaccess cd(dtAES,ua);
cSmartCardDataViaccess *entry=(cSmartCardDataViaccess *)smartcards.FindCardData(&cd);
if(entry) {
PRINTF(L_SC_INIT,"got AES key from smartcard.conf.");
SetKey(entry->aes);
}
return true;
}
| virtual bool cSmartCardViaccess::Init | ( | void | ) | [virtual] |
Implements cSmartCard.
| bool cSmartCardViaccess::Update | ( | int | pid, |
| int | caid, | ||
| const unsigned char * | data | ||
| ) | [virtual] |
Reimplemented from cSmartCard.
Definition at line 465 of file sc-viaccess.c.
References cAssembleData::Assembled(), AUTOMEM, data, cSmartCard::IsoWrite(), cParseViaccess::KeyNrFromNano(), cIdSet::MatchAndAssemble(), MAX_LEN, cParseViaccess::NanoStart(), SCT_LEN, start(), and cSmartCard::Status().
{
static unsigned char insf0[] = { 0xca,0xf0,0x00,0x00,0x00 };
static unsigned char ins18[] = { 0xca,0x18,0x00,0x00,0x00 };
static unsigned char insf4[] = { 0xca,0xf4,0x00,0x00,0x00 };
static unsigned char ins1c[] = { 0xca,0x1c,0x01,0x00,0x00 };
int updtype;
cAssembleData ad(data);
if(MatchAndAssemble(&ad,&updtype,0)) {
while((data=ad.Assembled())) {
const unsigned char *start=cParseViaccess::NanoStart(data);
int nanolen=SCT_LEN(data)-(start-data);
if(start && nanolen>=5) {
const unsigned char *nano81=0, *nano91=0, *nano92=0, *nano9e=0, *nanof0=0;
unsigned char *nanos18=AUTOMEM(nanolen+10);
bool provOK=false;
int len18=0, keynr=0;
while(nanolen>0) {
switch(start[0]) {
case 0x90:
if(SetProvider(&start[2])) {
provOK=true;
keynr=cParseViaccess::KeyNrFromNano(start);
}
break;
case 0x9E: // ADF
if(!nano91) { // not crypted
unsigned char custwp=sa0[3];
const unsigned char *afd=&start[2];
if(!(afd[31-custwp/8] & (1<<(custwp&7)))) { // not for this card
provOK=false; nanolen=0; // skip, next assemble data
break;
}
}
nano9e=start;
break;
case 0x81: nano81=start; break;
case 0x91: nano91=start; break;
case 0x92: nano92=start; break;
case 0xF0: nanof0=start; break;
default:
{
int l=start[1]+2;
memcpy(nanos18+len18,start,l);
len18+=l;
}
}
int l=start[1]+2;
start+=l; nanolen-=l;
}
if(provOK && nanof0) {
unsigned char buff[MAX_LEN*2];
if(nano9e) {
int l9e=nano9e[1]+2;
if(!nano91) {
insf0[3]=keynr;
insf0[4]=l9e;
if(!IsoWrite(insf0,nano9e) || !Status()) continue;
}
else {
int l91=nano91[1]+2;
insf4[3]=keynr;
insf4[4]=l91+l9e;
memcpy(buff,nano91,l91);
memcpy(buff+l91,nano9e,l9e);
if(!IsoWrite(insf4,buff) || !Status()) continue;
}
}
if(!nano92) {
int lf0=nanof0[1]+2;
ins18[2]=updtype>0 ? updtype-1 : updtype;
ins18[3]=keynr;
ins18[4]=len18+lf0;
memcpy(buff,nanos18,len18);
memcpy(buff+len18,nanof0,lf0);
if(IsoWrite(ins18,buff)) Status();
}
else if(nano81) {
int l92=nano92[1]+2, l81=nano81[1]+2, lf0=nanof0[1]+2;
ins1c[3]=keynr;
ins1c[4]=l92+l81+lf0;
memcpy(buff,nano92,l92);
memcpy(buff+l92,nano81,l81);
memcpy(buff+l92+l81,nanof0,lf0);
if(IsoWrite(ins1c,buff)) Status();
}
}
}
}
return true;
}
return false;
}
| virtual bool cSmartCardViaccess::Update | ( | int | pid, |
| int | caid, | ||
| const unsigned char * | data | ||
| ) | [virtual] |
Reimplemented from cSmartCard.