Beispiel #1
0
void cSystemIrd2::ProcessEMM(int pid, int caid, const unsigned char *data)
{
  int prov=0; //XXX how to get provider here??

  int len=SCT_LEN(data);
  unsigned char *emm=AUTOMEM(len);

  cPlainKey *pk;
  if(!(pk=keys.FindKey('I',caid,KEYSET(prov,TYPE_IV,0),16))) {
    PRINTF(L_SYS_EMM,"missing %04x %02x IV key",caid,prov);
    return;
    }
  unsigned char EMM_IV[16];
  pk->Get(EMM_IV);

  for(int keyno=0; keyno<2; keyno++) {
    if(!(pk=keys.FindKey('I',caid,KEYSET(prov,TYPE_PMK,keyno),16))) {
      PRINTF(L_SYS_EMM,"missing %04x %02x MK%d key",caid,prov,keyno);
      continue;
      }
    unsigned char PMK[16];
    pk->Get(PMK);

    if(!(pk=keys.FindKey('I',caid,KEYSET(prov,TYPE_SEED,1),16))) {
      PRINTF(L_SYS_EMM,"missing %04x %02x EMM key",caid,prov);
      return;
      }
    unsigned char EMM_Seed[16];
    pk->Get(EMM_Seed);
    PrepareSeed(EMM_Seed,PMK);

    memcpy(emm,data,len);
    Decrypt(&emm[10],EMM_IV,EMM_Seed,len-10);
    NanoDecrypt(emm,16,len-8,PMK,EMM_IV);
    memmove(emm+6,emm+7,len-7); // removing padding byte
    if(CalculateHash(EMM_Seed,EMM_IV,emm+3,len-4)) {
      HEXDUMP(L_SYS_RAWEMM,emm,len,"Irdeto2 RAWEMM");
      for(int i=15; i<len-9;) {
        int l=NANOLEN(emm[i+1]);
        switch(emm[i]) {
          case 0x10:
          case 0x50:
            if(l==0x13 && i+l<=len-9) {
              FoundKey();
              if(keys.NewKey('I',caid,KEYSET(prov,TYPE_OP,emm[i+2]>>2),&emm[i+3],16)) NewKey();
              }
            break;
          }
        i+=l;
        }
      break;
      }
Beispiel #2
0
int cProviderViaccess::Assemble(cAssembleData *ad)
{
  const unsigned char *data=ad->Data();
  int len=SCT_LEN(data);
  switch(data[0]) {
    case 0x8C:
    case 0x8D:
      if(data[0]!=sharedToggle) {
        free(sharedEmm);
        sharedLen=len;
        sharedEmm=(unsigned char *)malloc(len);
        if(sharedEmm) memcpy(sharedEmm,data,sharedLen);
        sharedToggle=data[0];
        }
      break;

    case 0x8E:
      if(sharedEmm) {
        unsigned char *tmp=AUTOMEM(len+sharedLen);
        unsigned char *ass=(unsigned char *)cParseViaccess::NanoStart(data);
        len-=(ass-data);
        if((data[6]&2)==0) {
          const int addrlen=len-8;
          len=0;
          tmp[len++]=0x9e;
          tmp[len++]=addrlen;
          memcpy(&tmp[len],&ass[0],addrlen); len+=addrlen;
          tmp[len++]=0xf0;
          tmp[len++]=0x08;
          memcpy(&tmp[len],&ass[addrlen],8); len+=8;
          }
        else {
          memcpy(tmp,ass,len);
          }
        ass=(unsigned char *)cParseViaccess::NanoStart(sharedEmm);
        int l=sharedLen-(ass-sharedEmm);
        memcpy(&tmp[len],ass,l); len+=l;

        ass=(unsigned char *)malloc(len+7);
        if(ass) {
          memcpy(ass,data,7);
          SortNanos(ass+7,tmp,len);
          SetSctLen(ass,len+4);
          ad->SetAssembled(ass);
          return 1; // assembled
          }
        }
      break;
    }
  return -1; // ignore
}
Beispiel #3
0
int cCardCryptoworks::Assemble(cAssembleData *ad)
{
  const unsigned char *data=ad->Data();
  int len=SCT_LEN(data);
  switch(data[0]) {
    case 0x82:
      return 0; // no assemble needed

    case 0x84:
      free(sharedEmm);
      sharedEmm=(unsigned char *)malloc(len);
      if(sharedEmm) {
        memcpy(sharedEmm,data,len);
        sharedLen=len;
        }
      break;

    case 0x86:
      if(sharedEmm) {
        int alen=len-5 + sharedLen-12;
        unsigned char *tmp=AUTOMEM(alen);
        memcpy(tmp,&data[5],len-5);
        memcpy(tmp+len-5,&sharedEmm[12],sharedLen-12);

        unsigned char *ass=(unsigned char *)malloc(alen+12);
        if(!ass) return -1; // ignore
        memcpy(ass,sharedEmm,12);
        SortNanos(ass+12,tmp,alen);
        SetSctLen(ass,alen+9);
        free(sharedEmm); sharedEmm=0;
        if(ass[11]==alen) { // sanity check
          ad->SetAssembled(ass);
          return 1; // assembled
          }
        }
      break;

    case 0x88:
    case 0x89:
      if(data[0]!=globalToggle) {
        globalToggle=data[0];
        unsigned int crc=crc32_le(0,data+1,len-1);
        if(crc!=globalCrc) {
          globalCrc=crc;
          return 0; // no assemble needed
          }
        }
      break;
    }
  return -1; // ignore
}
Beispiel #4
0
bool cSmartCardDataNagra::Parse(const char *line)
{
  bool isSK=false;
  int dlen=64;
  BN_set_word(exp,3);
  line=skipspace(line);
  unsigned char id[4];
  if(GetHex(line,id,sizeof(id))!=sizeof(id)) {
    PRINTF(L_CORE_LOAD,"smartcarddatanagra: format error: card id");
    return false;
    }
  cardid=UINT32_BE(id);
  line=skipspace(line);
  if(!strncasecmp(line,"SK",2)) { isSK=true; dlen=96; line+=2; }
  else {
    if(GetHex(line,bk,sizeof(bk))!=sizeof(bk)) {
      PRINTF(L_CORE_LOAD,"smartcarddatanagra: format error: boxkey");
      return false;
      }
    line=skipspace(line);
    if(!strncasecmp(line,"IRDMOD",6)) { isIrdMod=true; line+=6; }
    else if(!strncasecmp(line,"CARDMOD",7)) { isIrdMod=false; line+=7; }
    else {
      PRINTF(L_CORE_LOAD,"smartcarddatanagra: format error: IRDMOD/CARDMOD");
      return false;
      }
    }
  line=skipspace(line);

  unsigned char *buff=AUTOMEM(dlen);
  if(GetHex(line,buff,dlen)!=dlen) {
    PRINTF(L_CORE_LOAD,"smartcarddatanagra: format error: data block");
    return false;
    }
  if(!isSK) {
    mod.Get(buff,64);
    }
  else {
    struct SecondaryKey *sk=(struct SecondaryKey *)buff;
    if(UINT16_BE(sk->cs)!=CRC16(buff,sizeof(*sk)-sizeof(sk->cs),false)) {
      PRINTF(L_CORE_LOAD,"smartcarddatanagra: secondary key CRC failed");
      return false;
      }
    unsigned short e=UINT16_BE(sk->exp);
    if(e!=0x0003 && e!=CRC16(buff,12,false)) BN_set_word(exp,e);
    xxor(bk,sizeof(bk),sk->y1,sk->y2);
    mod.Get(sk->mod,sizeof(sk->mod));
    }
  return true;
}