bool cViaccess::Decrypt3(int provID, const cViacessExtendedKeys *work_keys, const unsigned char *ecw, int modeAES, unsigned char *des_data1, unsigned char *des_data2) { unsigned char dcw[16]; char hex1[34], hex2[34]; cLogLineBuff LineBuff(L_SYS_KEY); int i, pass; memcpy(dcw,ecw,16); LineBuff.Printf("ecw %s %s", HexStr(hex1, dcw, 8), HexStr(hex2, dcw+8, 8)); LineBuff.Flush(); if(modeAES==1) { cAES Aes; Aes.SetKey(work_keys->ekey); Aes.Decrypt(dcw, 16); } memcpy(des_data1,dcw,8); // needed for final xor for(pass = 0; pass < 2; pass++) { unsigned char *tmp_dcw=dcw + pass * 8, tmp[8]; for (i=0; i<4; i++) tmp[i] = tmp_dcw[i+4]; Via3Fct1(provID, work_keys, tmp); for (i=0; i<4; i++) tmp[i] = tmp_dcw[i]^tmp[i+4]; Via3Fct2(provID, work_keys, tmp); for (i=0; i<4; i++) tmp[i]^= work_keys->xkey[i+4]; for (i=0; i<4; i++) { tmp_dcw[i] = tmp_dcw[i+4]^tmp[i+4]; tmp_dcw[i+4] = tmp[i]; } Des(tmp_dcw, work_keys->key, DES_PC1 | DES_ECS2_DECRYPT); Des(tmp_dcw, work_keys->key + 8, DES_PC1 | DES_ECS2_CRYPT); Des(tmp_dcw, work_keys->key, DES_PC1 | DES_ECS2_DECRYPT); for (i=0; i<4; i++) tmp[i] = tmp_dcw[i+4]; Via3Fct2(provID, work_keys, tmp); for (i=0; i<4; i++) tmp[i] = tmp_dcw[i]^tmp[i+4]; Via3Fct1(provID, work_keys, tmp); for (i=0; i<4; i++) tmp[i]^= work_keys->xkey[i]; for (i=0; i<4; i++) { tmp_dcw[i] = tmp_dcw[i+4]^tmp[i+4]; tmp_dcw[i+4] = tmp[i]; } } xxor(dcw, 8, dcw, work_keys->ckey); xxor(dcw + 8, 8, dcw + 8, des_data1); if(modeAES==2) { cAES Aes; Aes.SetKey(work_keys->ekey); Aes.Decrypt(dcw, 16); } LineBuff.Printf("cw %s %s", HexStr(hex1, dcw, 8), HexStr(hex2, dcw+8, 8)); LineBuff.Flush(); for(i=0;i<16;i+=4) if(dcw[i+3] != ((dcw[i]+dcw[i+1]+dcw[i+2]) & 0xFF)) return false; memcpy(des_data1, dcw, 8); memcpy(des_data2, dcw+8, 8); return true; }
static void scam_generate_deskey(char *keyString, uint8_t *desKey) { uint8_t iv[8], *tmpKey; int32_t i, passLen, alignedPassLen; uint32_t key_schedule[32]; memset(iv, 0, 8); memset(desKey, 0, 8); passLen = keyString == NULL ? 0 : strlen(keyString); if(passLen > 1024) { passLen = 1024; } alignedPassLen = (passLen + 7) & -8; if(alignedPassLen == 0) alignedPassLen = 8; if(!cs_malloc(&tmpKey, alignedPassLen)) { return; } if(passLen == 0) { memset(tmpKey, 0xAA, 8); passLen = 8; } else { memcpy(tmpKey, keyString, passLen); } for(i=0; i<alignedPassLen-passLen; i++) { tmpKey[passLen+i] = (uint8_t)i; } xxor(desKey,8,tmpKey,iv); for(i=0; i<alignedPassLen; i+=8) { des_set_key(&tmpKey[i], key_schedule); des(&tmpKey[i], key_schedule, 1); xxor(desKey,8,desKey,&tmpKey[i]); } NULLFREE(tmpKey); }
void cIrdeto2::Encrypt(unsigned char *data, const unsigned char *seed, const unsigned char *key, int len) { ScheduleKey(key); len&=~7; const unsigned char *tmp=seed; for(int i=0; i<len; i+=8) { xxor(&data[i],8,&data[i],tmp); tmp=&data[i]; DES3(&data[i],0); } }
void cCamCryptNagra::Signature(unsigned char *sig, const unsigned char *key, const unsigned char *msg, int len) { unsigned char buff[16]; memcpy(buff,key,16); for(int i=0; i<len; i+=8) { idea.Decrypt(msg+i,8,buff,buff,0); xxor(buff,8,buff,&msg[i]); memcpy(&buff[8],buff,8); } memcpy(sig,buff,8); }
void cIrdeto2::Decrypt(unsigned char *data, const unsigned char *seed, const unsigned char *key, int len) { ScheduleKey(key); len&=~7; unsigned char buf[2][8]; int n=0; memcpy(buf[n],seed,8); for(int i=0; i<len; i+=8,data+=8,n^=1) { memcpy(buf[1-n],data,8); DES3(data,1); xxor(data,8,data,buf[n]); } }
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; }
bool cIrdeto2::CalculateHash(const unsigned char *key, const unsigned char *iv, const unsigned char *data, int len) { ScheduleKey(key); unsigned char cbuff[8]; memset(cbuff,0,sizeof(cbuff)); len-=8; for(int y=0; y<len; y+=8) { if(y<len-8) { xxor(cbuff,8,cbuff,&data[y]); LDUMP(L_SYS_VERBOSE,cbuff,8,"3DES XOR in:"); } else { int l=len-y; xxor(cbuff,l,cbuff,&data[y]); xxor(cbuff+l,8-l,cbuff+l,iv+8); LDUMP(L_SYS_VERBOSE,cbuff,8,"3DES XOR(%d) in:",8-l); } DES3(cbuff,0); LDUMP(L_SYS_VERBOSE,cbuff,8,"3DES out:"); } LDUMP(L_SYS_VERBOSE,cbuff,8,"CryptBuffer:"); LDUMP(L_SYS_VERBOSE,&data[len],8,"MACBuffer:"); return memcmp(cbuff,&data[len],8)==0; }
bool cViaccess::Decrypt26(const cViacessExtendedKeys *work_keys, const unsigned char *ecw, unsigned char *des_data1, unsigned char *des_data2) { unsigned char dcw[16]; char hex1[34], hex2[34]; cLogLineBuff LineBuff(L_SYS_KEY); int i, pass; memcpy(dcw,ecw,16); LineBuff.Printf("ecw %s %s", HexStr(hex1, dcw, 8), HexStr(hex2, dcw+8, 8)); LineBuff.Flush(); for(pass = 0; pass < 2; pass++) { unsigned char *tmp_dcw=dcw + pass * 8, tmp[8]; for(i = 0; i < 8; i++) tmp[i] = work_keys->tkey[tmp_dcw[i]]; for(i = 0; i < 8; i++) tmp_dcw[i] = tmp[work_keys->pkey[i]]; Des(tmp_dcw, work_keys->dkey, DES_PC1 | DES_ECS2_CRYPT); xxor(tmp_dcw, 8, tmp_dcw, work_keys->xkey); Des(tmp_dcw, work_keys->key, DES_PC1 | DES_ECS2_DECRYPT); Des(tmp_dcw, work_keys->key + 8, DES_PC1 | DES_ECS2_CRYPT); Des(tmp_dcw, work_keys->key, DES_PC1 | DES_ECS2_DECRYPT); xxor(tmp_dcw, 8, tmp_dcw, work_keys->xkey); Des(tmp_dcw, work_keys->dkey, DES_PC1 | DES_ECS2_DECRYPT); for(i = 0; i < 8; i++) tmp[work_keys->pkey[i]] = tmp_dcw[i]; for(i = 0; i < 8; i++) tmp_dcw[i] = work_keys->tkey[tmp[i]]; } xxor(dcw, 8, dcw, work_keys->ckey); xxor(dcw + 8, 8, dcw + 8, ecw); LineBuff.Printf("cw %s %s", HexStr(hex1, dcw, 8), HexStr(hex2, dcw+8, 8)); LineBuff.Flush(); for(i=0;i<16;i+=4) if(dcw[i+3] != ((dcw[i]+dcw[i+1]+dcw[i+2]) & 0xFF)) return false; memcpy(des_data1, dcw, 8); memcpy(des_data2, dcw+8, 8); return true; }