예제 #1
0
bool cCamCryptNagra::MakeSessionKey(unsigned char *out, const unsigned char *camdata)
{
  if(!hasMod) return false;
  if(LOG(L_SC_PROC)) {
    unsigned char bb[64];
    camMod.Put(bb,sizeof(bb));
    LDUMP(L_SC_PROC,bb,sizeof(bb),"Sessionkey negotiation CAMMOD:");
    }
  //decrypt $2A data here and prepare $2B reply
  if(rsa.RSA(out,camdata,64,camExp,camMod)!=64) return false;
  LDUMP(L_SC_PROC,out,64,"CMD 2A/26 after RSA:");

  unsigned char key[16], sess[16];
  InitKey(key,signature,cardid);
  LDUMP(L_SC_PROC,key,16,"first IDEA key: ");
  Signature(sess,key,out,32);
  memcpy(key,sess,8);
  memcpy(key+8,sess,8);
  LDUMP(L_SC_PROC,key,16,"second IDEA key:");
  Signature(sess+8,key,out,32);
  LDUMP(L_SC_PROC,sess,16,"SESSION KEY:    ");
  idea.SetDecKey(sess,&sessKey);

  if(rsa.RSA(out,out,64,camExp,camMod)!=64) return false;
  LDUMP(L_SC_PROC,out,64,"CMD 2B/27 data:");
  return true;
}
예제 #2
0
bool cCamCryptNagra::DecryptDT08(const unsigned char *dt08, unsigned int irdid, cBN *irdmod, bool fakeid)
{
  if(LOG(L_SC_PROC)) {
    unsigned char bb[64];
    irdmod->Put(bb,sizeof(bb));
    LDUMP(L_SC_PROC,bb,sizeof(bb),"DT08 decrypt IRDID: %08x IRDMOD:",irdid);
    }
  unsigned char buff[72];
  if(rsa.RSA(buff,dt08+1,64,camExp,*irdmod)!=64) return false;
  memcpy(buff+64,dt08+1+64,8);
  buff[63]|=dt08[0]&0x80;
  LDUMP(L_SC_PROC,buff,72,"DT08 after RSA");

  unsigned char key[16];
  InitKey(key,boxkey,irdid);
  LDUMP(L_SC_PROC,key,16,"DT08 IDEA key");
  IdeaKS dks;
  idea.SetDecKey(key,&dks);
  idea.Decrypt(buff,72,&dks,0);
  LDUMP(L_SC_PROC,buff,72,"DT08 after IDEA");

  memcpy(signature,buff,8);
  LDUMP(L_SC_PROC,signature,8,"signature");
  BYTE4_BE(buff  ,0);
  BYTE4_BE(buff+4,fakeid?0xFFFFFFFF:cardid);
  Signature(buff,key,buff,72);
  LDUMP(L_SC_PROC,buff,8,"check sig");
  if(memcmp(signature,buff,8)) {
    PRINTF(L_SC_PROC,"DT08 signature failed");
    return false;
    }
  BN_bin2bn(buff+8,64,camMod);
  hasMod=true;
  return true;
}
예제 #3
0
bool cSystemConax::ProcessECM(const cEcmInfo *ecm, unsigned char *source)
{
  int length=source[4]-2;
  const int keyid=source[6];
  const int nano=source[5];
  source+=7;

  cKeySnoop ks(this,'C',keyid,'M');
  cPlainKey *pk;
  cBN mod, exp;
  if(!(pk=keys.FindKey('C',keyid,'E',-1))) {
    if(doLog) PRINTF(L_SYS_KEY,"missing %02X E key",keyid);
    return false;
    }
  pk->Get(exp);
  if(!(pk=keys.FindKey('C',keyid,'M',-1))) {
    if(doLog) PRINTF(L_SYS_KEY,"missing %02X M key",keyid);
    return false;
    }
  pk->Get(mod);

  for(int i=length ; i>0 ;) {
    int index=i-64;
    if(index<0) index=0;
    if(rsa.RSA(source+index,source+index,64,exp,mod,false)<=0) {
      if(doLog) PRINTF(L_SYS_CRYPTO,"RSA failed");
      return false;
      }
    if(nano==0x63) {
      // nano 0x63 block only decodes to 63 bytes
      memmove(source+index,source+index+1,length-(index+1));
      length-=1;
      }
    i-=(i%60 && index) ? i%60 : 64;
    }

  static const unsigned char hash[] = { 0x05,0x00,0x05 };
  if(memcmp(hash,source+2,3) || memcmp(source+5,source+length-5,3)) {
    if(doLog) PRINTF(L_SYS_ECM,"signature check failed");
    return false;
    }

  ParseECM(source+10,length-10);
  ks.OK(pk);
  return true;
}