#include "../globals.h" #ifdef WITH_CARDREADER #include "../oscam-lock.h" #include "../oscam-string.h" #include "icc_async.h" #include "protocol_t0.h" #include "io_serial.h" #include "ifd_phoenix.h" #include "../oscam-time.h" #ifdef READER_NAGRA_MERLIN #include "../cscrypt/fast_aes.h" #include "../cscrypt/sha256.h" #include "../cscrypt/mdc2.h" #include "../cscrypt/idea.h" #endif #define OK 0 #define ERROR 1 // Default T0/T14 settings #define DEFAULT_WI 10 // Default T1 settings #define DEFAULT_IFSC 32 #define MAX_IFSC 251 // Cannot send > 255 buffer #define DEFAULT_CWI 13 #define DEFAULT_BWI 4 #define EDC_LRC 0 #define PPS_MAX_LENGTH 6 #define PPS_HAS_PPS1(block) ((block[1] & 0x10) == 0x10) #define PPS_HAS_PPS2(block) ((block[1] & 0x20) == 0x20) #define PPS_HAS_PPS3(block) ((block[1] & 0x40) == 0x40) static uint16_t tempfi; // used to capture FI and use it for rounding or not static void ICC_Async_InvertBuffer(struct s_reader *reader, uint32_t size, unsigned char *buffer); static int32_t Parse_ATR(struct s_reader *reader, ATR *atr, uint16_t deprecated); static int32_t PPS_Exchange(struct s_reader *reader, unsigned char *params, uint32_t *length); static uint32_t PPS_GetLength(unsigned char *block); static int32_t InitCard(struct s_reader *reader, ATR *atr, unsigned char FI, uint32_t D, unsigned char N, uint16_t deprecated); static uint32_t ETU_to_us(struct s_reader *reader, uint32_t ETU); static unsigned char PPS_GetPCK(unsigned char *block, uint32_t length); static int32_t SetRightParity(struct s_reader *reader); #ifdef READER_NAGRA_MERLIN static void calculate_cak7_vars(struct s_reader *reader, const ATR *atr) { uint8_t aes_key[32]; const uint8_t aes_iv[] = { 0x4E, 0x61, 0x67, 0x72, 0x61, 0x63, 0x61, 0x72, 0x64, 0x28, 0x63, 0x29, 0x32, 0x30, 0x30, 0x36 }; // Nagracard(c)2006 mbedtls_sha256_context ctx_sha256; mbedtls_sha256_init(&ctx_sha256); mbedtls_sha256_starts(&ctx_sha256, 0); mbedtls_sha256_update(&ctx_sha256, atr->hb, atr->hbn); mbedtls_sha256_finish(&ctx_sha256, aes_key); mbedtls_sha256_free(&ctx_sha256); memcpy(reader->cak7_aes_key,aes_key,32); memcpy(reader->cak7_aes_iv,aes_iv,16); char tmp[128]; rdr_log(reader, "Initial AES: %s", cs_hexdump(1, reader->cak7_aes_key + 16, 16, tmp, sizeof(tmp))); } void calculate_cak7_cmd(struct s_reader *reader, uint8_t *cmdin,uint8_t cmdlen,uint8_t *cmdout) { uint32_t crc = ccitt32_crc(cmdin+4, cmdlen-4); i2b_buf(4, crc, cmdin); rdr_log_dump_dbg(reader, D_READER, cmdin, cmdlen, "preparing data for writing to cardreader"); AesCtx ctx; AesCtxIni(&ctx, reader->cak7_aes_iv, &reader->cak7_aes_key[16], KEY128, CBC); AesEncrypt(&ctx, cmdin, cmdout, cmdlen); } void do_cak7_cmd(struct s_reader *reader,unsigned char *cta_res, uint16_t *p_cta_lr,uint8_t *data,uint8_t inlen,uint8_t resplen) { reader->cak7_seq++; uint8_t req[inlen+5+1]; // +head+len memset(req,0x00,sizeof(req)); // head req[0]=0x80; req[1]=0xCA; if(reader->protocol_type == ATR_PROTOCOL_TYPE_T0) { req[4]=inlen + 1; } else { req[4]=inlen; } req[sizeof(req)-1]=resplen; data[4]=(reader->cak7_seq>>16)&0xFF; data[5]=(reader->cak7_seq>>8)&0xFF; data[6]=(reader->cak7_seq)&0xFF; calculate_cak7_cmd(reader,data,inlen,&req[5]); rdr_log_dump_dbg(reader, D_READER, req, sizeof(req), "write to cardreader"); if(!ICC_Async_CardWrite(reader, req, sizeof(req), cta_res, p_cta_lr)) { if(reader->protocol_type == ATR_PROTOCOL_TYPE_T0) { if(cta_res[*p_cta_lr - 2] == 0x61) { uint8_t resp[] = {0x00,0xC0,0x00,0x00,0x00}; memcpy(resp + 4,&cta_res[*p_cta_lr - 1],1); rdr_log_dump_dbg(reader, D_READER, resp, sizeof(resp), "write to cardreader"); if(!ICC_Async_CardWrite(reader, resp, sizeof(resp), cta_res, p_cta_lr)) { AesCtx ctx; AesCtxIni(&ctx, reader->cak7_aes_iv, &reader->cak7_aes_key[16], KEY128, CBC); AesDecrypt(&ctx, cta_res, cta_res, *p_cta_lr-2); } else { *p_cta_lr=0; } } else if(cta_res[*p_cta_lr - 2] == 0x6F && cta_res[*p_cta_lr - 1] == 0x01) { rdr_log(reader, "card answered 6F01 - trying one more time"); rdr_log_dump_dbg(reader, D_READER, req, sizeof(req), "write to cardreader"); if(!ICC_Async_CardWrite(reader, req, sizeof(req), cta_res, p_cta_lr)) { if(cta_res[*p_cta_lr - 2] == 0x61) { uint8_t resp[] = {0x00,0xC0,0x00,0x00,0x00}; memcpy(resp + 4,&cta_res[*p_cta_lr - 1],1); rdr_log_dump_dbg(reader, D_READER, resp, sizeof(resp), "write to cardreader"); if(!ICC_Async_CardWrite(reader, resp, sizeof(resp), cta_res, p_cta_lr)) { AesCtx ctx; AesCtxIni(&ctx, reader->cak7_aes_iv, &reader->cak7_aes_key[16], KEY128, CBC); AesDecrypt(&ctx, cta_res, cta_res, *p_cta_lr-2); } else { *p_cta_lr=0; } } else if(cta_res[*p_cta_lr - 2] == 0x6F && cta_res[*p_cta_lr - 1] == 0x01) { rdr_log(reader, "card needs reinit"); } } else { *p_cta_lr=0; } } } else { if(cta_res[*p_cta_lr - 2] == 0x6F && cta_res[*p_cta_lr - 1] == 0x01) { rdr_log(reader, "card answered 6F01 - trying one more time"); rdr_log_dump_dbg(reader, D_READER, req, sizeof(req), "write to cardreader"); if(!ICC_Async_CardWrite(reader, req, sizeof(req), cta_res, p_cta_lr)) { if(cta_res[*p_cta_lr - 2] == 0x6F && cta_res[*p_cta_lr - 1] == 0x01) { rdr_log(reader, "card needs reinit"); } else { AesCtx ctx; AesCtxIni(&ctx, reader->cak7_aes_iv, &reader->cak7_aes_key[16], KEY128, CBC); AesDecrypt(&ctx, cta_res, cta_res, *p_cta_lr-2); } } else { *p_cta_lr=0; } } else { AesCtx ctx; AesCtxIni(&ctx, reader->cak7_aes_iv, &reader->cak7_aes_key[16], KEY128, CBC); AesDecrypt(&ctx, cta_res, cta_res, *p_cta_lr-2); } } } else { *p_cta_lr=0; } } static void calculate_changerom_cmd(struct s_reader *reader, const ATR *atr, uint8_t *cmd) { uint8_t cmd_data[] = { 0xCC, 0xCC, 0xCC, 0xCC, 0x00, 0x00, 0x01, 0x01, 0x01, 0x95, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC }; calculate_cak7_vars(reader,atr); calculate_cak7_cmd(reader,cmd_data,sizeof(cmd_data),cmd); } #endif int32_t ICC_Async_Device_Init(struct s_reader *reader) { const struct s_cardreader *crdr_ops = reader->crdr; if (!crdr_ops) return ERROR; reader->fdmc = -1; rdr_log_dbg(reader, D_IFD, "Opening device %s", reader->device); reader->written = 0; int32_t ret = crdr_ops->reader_init(reader); if(ret == OK) { rdr_log_dbg(reader, D_IFD, "Device %s successfully opened", reader->device); } else { if(reader->typ != R_SC8in1) { NULLFREE(reader->crdr_data); } rdr_log_dbg(reader, D_IFD, "ERROR: Can't open %s device", reader->device); } return ret; } int32_t ICC_Async_Init_Locks(void) { // Init device specific locks here, called from init thread // before reader threads are running struct s_reader *rdr; LL_ITER itr = ll_iter_create(configured_readers); while((rdr = ll_iter_next(&itr))) { const struct s_cardreader *crdr_ops = rdr->crdr; if (!crdr_ops || !crdr_ops->lock_init) continue; crdr_ops->lock_init(rdr); } return OK; } int32_t ICC_Async_GetStatus(struct s_reader *reader, int32_t *card) { const struct s_cardreader *crdr_ops = reader->crdr; if (!crdr_ops) { return ERROR; } if (reader->typ == R_SMART && reader->smartdev_found >= 4) { reader->statuscnt = reader->statuscnt + 1; if (reader->statuscnt == 6) { int32_t in = 0; call(crdr_ops->get_status(reader, &in)); if(in) { reader->modemstat = 1; *card = 1; reader->statuscnt = 0; } else { reader->modemstat = 0; *card = 0; reader->statuscnt = 0; } return OK; } else { *card = reader->modemstat; return OK; } } else { int32_t in = 0; call(crdr_ops->get_status(reader, &in)); if(in) { *card = 1; } else { *card = 0; } return OK; } } int32_t ICC_Async_Activate(struct s_reader *reader, ATR *atr, uint16_t deprecated) { rdr_log_dbg(reader, D_IFD, "Activating card"); const struct s_cardreader *crdr_ops = reader->crdr; if (!crdr_ops) return ERROR; reader->current_baudrate = DEFAULT_BAUDRATE; if(reader->atr[0] != 0 && !reader->ins7e11_fast_reset) { rdr_log(reader, "Using ATR from reader config"); ATR_InitFromArray(atr, reader->atr, ATR_MAX_SIZE); } else { reader->crdr_flush = crdr_ops->flush; // Flush flag may be changed for each reader call(crdr_ops->activate(reader, atr)); if(crdr_ops->skip_extra_atr_parsing #ifdef READER_NAGRA_MERLIN && reader->cak7_mode == 0 #endif ) { return OK; } } uint8_t atrarr[ATR_MAX_SIZE]; uint32_t atr_size; ATR_GetRaw(atr, atrarr, &atr_size); char tmp[atr_size * 3 + 1]; rdr_log(reader, "ATR: %s", cs_hexdump(1, atrarr, atr_size, tmp, sizeof(tmp))); memcpy(reader->card_atr, atrarr, atr_size); reader->card_atr_length = atr_size; // Get ICC reader->convention if(ATR_GetConvention(atr, &(reader->convention)) != ATR_OK) { rdr_log(reader, "ERROR: Could not read reader->convention"); reader->convention = 0; reader->protocol_type = 0; return ERROR; } reader->protocol_type = ATR_PROTOCOL_TYPE_T0; // Parse_ATR and InitCard need to be included in lock because they change parity of serial port if(crdr_ops->lock) { crdr_ops->lock(reader); } int32_t ret = Parse_ATR(reader, atr, deprecated); if(crdr_ops->unlock) { crdr_ops->unlock(reader); } if(ret) { rdr_log(reader, "ERROR: Parse_ATR returned error"); return ERROR; } #ifdef READER_NAGRA_MERLIN reader->cak7type = 0; ATR_GetRaw(atr, atrarr, &atr_size); if((memcmp(atrarr + 8, "DNASP40", 7) == 0) || (memcmp(atrarr + 11, "DNASP41", 7) == 0) || (memcmp(atrarr + 11, "DNASP48", 7) == 0)) { rdr_log(reader, "card needs reset before init"); memset(atr, 0, 1); call(crdr_ops->activate(reader, atr)); //try to read the atr of this layer ATR_GetRaw(atr, atrarr, &atr_size); rdr_log(reader,"ATR: %s", cs_hexdump(1, atrarr, atr_size, tmp, sizeof(tmp))); // Parse_ATR and InitCard need to be included in lock because they change parity of serial port if(crdr_ops->lock) { crdr_ops->lock(reader); } int32_t ret1 = Parse_ATR(reader, atr, deprecated); if(crdr_ops->unlock) { crdr_ops->unlock(reader); } if(ret1) { rdr_log(reader, "ERROR: Parse_ATR returned error"); return ERROR; } } if((memcmp(atrarr + 8, "DNASP4", 6) == 0) || (memcmp(atrarr + 11, "DNASP4", 6) == 0)) { rdr_log(reader, "detected card in CAK7 mode"); calculate_cak7_vars(reader, atr); if((atrarr[2] == 0x95) && (atrarr[3] == 0x00) && (atrarr[4] == 0xFF) && (atrarr[5] == 0x50) && (atrarr[6] == 0x80) && (atrarr[7] == 0x1C)) { reader->cak7type = 3; } else { reader->cak7type = 1; } } else if(((memcmp(atrarr + 7, "pp", 2) == 0 && ((atrarr[9]&0x0F) >= 10)) || (memcmp(atrarr + 11, "DNASP18", 7) == 0) || (memcmp(atrarr + 11, "DNASP19", 7) == 0) || (memcmp(atrarr + 11, "DNASP1A", 7) == 0)) && reader->cak7_mode) { rdr_log(reader, "detected card in CAK6/Seca mode -> try switch to Nagra CAK7"); uint8_t changerom_handshake[22]; memset(changerom_handshake, 0x00, 22); calculate_changerom_cmd(reader, atr, &changerom_handshake[5]); memset(reader->rom, 0, 15); unsigned char cta_res[CTA_RES_LEN]; memset(cta_res, 0, CTA_RES_LEN); uint16_t cta_lr; changerom_handshake[0] = 0x80; changerom_handshake[1] = 0xCA; changerom_handshake[4] = 0x11; // 0x11: length of data we will send uint8_t cta_res1_ok = 0x61; uint8_t cta_res2_ok = 0x10; if(reader->protocol_type != ATR_PROTOCOL_TYPE_T0) { //changerom_handshake[0] = 0x80; // fix for mipsel router changerom_handshake[4] = 0x10; // 0x10: length of data we will send cta_res1_ok = 0x90; cta_res2_ok = 0x00; } changerom_handshake[21] = 0x10; reader->cak7type = 1; rdr_log_dump_dbg(reader, D_READER, changerom_handshake, sizeof(changerom_handshake), "write to cardreader"); if(!ICC_Async_CardWrite(reader, changerom_handshake, sizeof(changerom_handshake), cta_res, &cta_lr)) { if(cta_res[cta_lr-2] == cta_res1_ok && cta_res[cta_lr-1] == cta_res2_ok) { if(reader->protocol_type == ATR_PROTOCOL_TYPE_T0) { uint8_t resp[] = {0x00,0xC0,0x00,0x00,0x00}; memcpy(resp + 4,&cta_res[cta_lr - 1],1); rdr_log_dump_dbg(reader, D_READER, resp, sizeof(resp), "write to cardreader"); if(!ICC_Async_CardWrite(reader, resp, sizeof(resp), cta_res, &cta_lr)) { AesCtx ctx; AesCtxIni(&ctx, reader->cak7_aes_iv, &reader->cak7_aes_key[16], KEY128, CBC); AesDecrypt(&ctx, cta_res, cta_res, cta_lr-2); rdr_log_dump_dbg(reader, D_READER, cta_res, cta_lr, "Decrypted Answer:"); } else { return ERROR; } } else { AesCtx ctx; AesCtxIni(&ctx, reader->cak7_aes_iv, &reader->cak7_aes_key[16], KEY128, CBC); AesDecrypt(&ctx, cta_res, cta_res, cta_lr-2); rdr_log_dump_dbg(reader, D_READER, cta_res, cta_lr, "Decrypted Answer:"); } rdr_log(reader, "switch nagra layer OK"); memset(atr, 0, 1); call(crdr_ops->activate(reader, atr)); //try to read the atr of this layer ATR_GetRaw(atr, atrarr, &atr_size); rdr_log(reader,"ATR: %s", cs_hexdump(1, atrarr, atr_size, tmp, sizeof(tmp))); calculate_cak7_vars(reader, atr); if(reader->protocol_type == ATR_PROTOCOL_TYPE_T0) { reader->cak7type = 3; } else { reader->cak7type = 1; } if(crdr_ops->lock) { crdr_ops->lock(reader); } int32_t ret2 = Parse_ATR(reader, atr, deprecated); if(crdr_ops->unlock) { crdr_ops->unlock(reader); } if(ret2) { rdr_log(reader, "ERROR: Parse_ATR returned error"); return ERROR; } } else { rdr_log(reader,"Switch to nagra layer failed!"); return ERROR; } } else { rdr_log(reader,"Switch to nagra layer command failed!"); return ERROR; } memcpy(reader->card_atr, atrarr, atr_size); reader->card_atr_length = atr_size; memcpy(reader->rom, atr->hb, (atr->hbn>15)?15:atr->hbn); // get historical bytes from atr } #endif rdr_log_dbg(reader, D_READER, "Card successfully activated"); return OK; } int32_t ICC_Async_CardWrite(struct s_reader *reader, unsigned char *command, uint16_t command_len, unsigned char *rsp, uint16_t *lr) { const struct s_cardreader *crdr_ops = reader->crdr; if (!crdr_ops) return ERROR; int32_t ret; *lr = 0; //will be returned in case of error if(crdr_ops->card_write) { call(crdr_ops->card_write(reader, command, rsp, lr, command_len)); rdr_log_dump_dbg(reader, D_READER, rsp, *lr, "Answer from cardreader:"); return OK; } if(crdr_ops->lock) { crdr_ops->lock(reader); } int32_t try = 1; uint16_t type = 0; do { if(try > 1) { rdr_log(reader, "Warning: needed try nr %i, next ECM has some delay", try); } switch(reader->protocol_type) { case ATR_PROTOCOL_TYPE_T0: ret = Protocol_T0_Command(reader, command, command_len, rsp, lr); type = 0; break; case ATR_PROTOCOL_TYPE_T1: ret = Protocol_T1_Command(reader, command, command_len, rsp, lr); type = 1; if(ret != OK && !crdr_ops->skip_t1_command_retries #ifdef READER_NAGRA_MERLIN && reader->cak7type == 0 #endif ) { //try to resync rdr_log(reader, "Resync error: readtimeouts %d/%d (max/min) us, writetimeouts %d/%d (max/min) us", reader->maxreadtimeout, reader->minreadtimeout, reader->maxwritetimeout, reader->minwritetimeout); unsigned char resync[] = { 0x21, 0xC0, 0x00, 0xE1 }; ret = Protocol_T1_Command(reader, resync, sizeof(resync), rsp, lr); if(ret == OK) { //reader->ifsc = DEFAULT_IFSC; // tryfix cardtimeouts: ifsc is setup at card init, on resync it should not return to default_ifsc rdr_log(reader, "T1 Resync command successful ifsc = %i", reader->ifsc); ret = ERROR; } else { rdr_log(reader, "T1 Resync command error, trying to reactivate!"); ATR atr; ICC_Async_Activate(reader, &atr, reader->deprecated); if(crdr_ops->unlock) { crdr_ops->unlock(reader); } return ERROR; } } break; case ATR_PROTOCOL_TYPE_T14: ret = Protocol_T14_ExchangeTPDU(reader, command, command_len, rsp, lr); type = 14; break; default: rdr_log(reader, "ERROR: Unknown protocol type %i", reader->protocol_type); type = 99; // use 99 for unknown. ret = ERROR; } try++; } while((try < 3) && (ret != OK) && (((type == 0 || type == 1) #ifdef READER_NAGRA_MERLIN && reader->cak7type == 0 #endif ) || type == 14)); // always do one retry when failing if(crdr_ops->unlock) { crdr_ops->unlock(reader); } if(ret) { rdr_log_dbg(reader, D_TRACE, "ERROR: Protocol_T%d_Command returns error", type); return ERROR; } rdr_log_dump_dbg(reader, D_READER, rsp, *lr, "Answer from cardreader:"); return OK; } int32_t ICC_Async_GetTimings(struct s_reader *reader, uint32_t wait_etu) { int32_t timeout = ETU_to_us(reader, wait_etu); rdr_log_dbg(reader, D_IFD, "Setting timeout to %i ETU (%d us)", wait_etu, timeout); return timeout; } int32_t ICC_Async_Transmit(struct s_reader *reader, uint32_t size, uint32_t expectedlen, unsigned char *data, uint32_t delay, uint32_t timeout) { const struct s_cardreader *crdr_ops = reader->crdr; if (!crdr_ops) return ERROR; if(expectedlen) { rdr_log_dbg(reader, D_IFD, "Transmit size %d bytes, expected len %d bytes, delay %d us, timeout=%d us", size, expectedlen, delay, timeout); } else { rdr_log_dbg(reader, D_IFD, "Transmit size %d bytes, delay %d us, timeout=%d us", size, delay, timeout); } rdr_log_dump_dbg(reader, D_IFD, data, size, "Transmit:"); unsigned char *sent = data; if(reader->convention == ATR_CONVENTION_INVERSE && crdr_ops->need_inverse) { ICC_Async_InvertBuffer(reader, size, sent); } call(crdr_ops->transmit(reader, sent, size, expectedlen, delay, timeout)); rdr_log_dbg(reader, D_IFD, "Transmit successful"); if(reader->convention == ATR_CONVENTION_INVERSE && crdr_ops->need_inverse) { // revert inversion cause the code in protocol_t0 is accessing buffer after transmit ICC_Async_InvertBuffer(reader, size, sent); } return OK; } int32_t ICC_Async_Receive(struct s_reader *reader, uint32_t size, unsigned char *data, uint32_t delay, uint32_t timeout) { const struct s_cardreader *crdr_ops = reader->crdr; if (!crdr_ops) return ERROR; rdr_log_dbg(reader, D_IFD, "Receive size %d bytes, delay %d us, timeout=%d us", size, delay, timeout); call(crdr_ops->receive(reader, data, size, delay, timeout)); rdr_log_dbg(reader, D_IFD, "Receive successful"); if(reader->convention == ATR_CONVENTION_INVERSE && crdr_ops->need_inverse == 1) { ICC_Async_InvertBuffer(reader, size, data); } return OK; } int32_t ICC_Async_Close(struct s_reader *reader) { const struct s_cardreader *crdr_ops = reader->crdr; if (!crdr_ops) return ERROR; rdr_log_dbg(reader, D_IFD, "Closing device %s", reader->device); call(crdr_ops->close(reader)); if(reader->typ != R_SC8in1) { NULLFREE(reader->crdr_data); NULLFREE(reader->csystem_data); } rdr_log_dbg(reader, D_IFD, "Device %s successfully closed", reader->device); return OK; } void ICC_Async_DisplayMsg(struct s_reader *reader, char *msg) { const struct s_cardreader *crdr_ops = reader->crdr; if (!crdr_ops || !crdr_ops->display_msg) { return; } crdr_ops->display_msg(reader, msg); } int32_t ICC_Async_Reset(struct s_reader *reader, struct s_ATR *atr, int32_t (*rdr_activate_card)(struct s_reader *, struct s_ATR *, uint16_t deprecated), int32_t (*rdr_get_cardsystem)(struct s_reader *, struct s_ATR *)) { const struct s_cardreader *crdr_ops = reader->crdr; if (!crdr_ops || !crdr_ops->do_reset) { return 0; } return crdr_ops->do_reset(reader, atr, rdr_activate_card, rdr_get_cardsystem); } static uint32_t ICC_Async_GetClockRate(int32_t cardmhz) { switch(cardmhz) { case 357: case 358: return (372L * 9600L); case 368: return (384L * 9600L); default: return (cardmhz * 10000L); } } static int32_t ICC_Async_GetPLL_Divider(struct s_reader *reader) { if(reader->divider != 0) { return reader->divider; } if(reader->cardmhz != 8300) // Check dreambox is not DM7025 { float divider; divider = ((float) reader->cardmhz) / ((float) reader->mhz); if (tempfi == 9) reader->divider = (int32_t) divider; // some card's runs only when slightly oveclocked like HD02 else { reader->divider = (int32_t) divider; if(divider > reader->divider) { reader->divider++; // to prevent over clocking, ceil (round up) the divider } } rdr_log_dbg(reader, D_DEVICE, "PLL maxmhz = %.2f, wanted mhz = %.2f, divider used = %d, actualcardclock=%.2f", (float) reader->cardmhz / 100, (float) reader->mhz / 100, reader->divider, (float) reader->cardmhz / reader->divider / 100); reader->mhz = reader->cardmhz / reader->divider; } else // STB is DM7025 { int32_t i, dm7025_clock_freq[] = {518, 461, 395, 360, 319, 296, 267, 244, 230, 212, 197}, dm7025_PLL_setting[] = {6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, t_cardmhz = reader->mhz; for(i = 0; i < 11; i++) if(t_cardmhz >= dm7025_clock_freq[i]) { break; } if(i > 10) { i = 10; } reader->mhz = dm7025_clock_freq[i]; reader->divider = dm7025_PLL_setting[i]; /*Nicer way of codeing is: reader->divider = i + 6;*/ rdr_log_dbg(reader, D_DEVICE, "DM7025 PLL maxmhz = %.2f, wanted mhz = %.2f, PLL setting used = %d, actualcardclock=%.2f", (float) reader->cardmhz / 100, (float) t_cardmhz / 100, reader->divider, (float) reader->mhz / 100); } return reader->divider; } static void ICC_Async_InvertBuffer(struct s_reader *reader, uint32_t size, unsigned char *buffer) { uint32_t i; rdr_log_dbg(reader, D_IFD, "%s: size=%u buf[0]=%02x", __func__, size, buffer[0]); for(i = 0; i < size; i++) { buffer[i] = ~(INVERT_BYTE(buffer[i])); } } static int32_t Parse_ATR(struct s_reader *reader, ATR *atr, uint16_t deprecated) { unsigned char FI = ATR_DEFAULT_FI; uint32_t D = ATR_DEFAULT_D; uint32_t N = ATR_DEFAULT_N; int32_t ret; char tmp[256]; int32_t numprot = atr->pn; //if there is a trailing TD, this number is one too high unsigned char tx; if(ATR_GetInterfaceByte(atr, numprot - 1, ATR_INTERFACE_BYTE_TD, &tx) == ATR_OK) if((tx & 0xF0) == 0) { numprot--; } int32_t i, point; char txt[50]; bool OffersT[3]; //T14 stored as T2 for(i = 0; i <= 2; i++) { OffersT[i] = 0; } for(i = 1; i <= numprot; i++) { point = 0; if(ATR_GetInterfaceByte(atr, i, ATR_INTERFACE_BYTE_TA, &tx) == ATR_OK) { snprintf((char *)txt + point, sizeof(txt) - point, "TA%i=%02X ", i, tx); point += 7; } if(ATR_GetInterfaceByte(atr, i, ATR_INTERFACE_BYTE_TB, &tx) == ATR_OK) { snprintf((char *)txt + point, sizeof(txt) - point, "TB%i=%02X ", i, tx); point += 7; } if(ATR_GetInterfaceByte(atr, i, ATR_INTERFACE_BYTE_TC, &tx) == ATR_OK) { snprintf((char *)txt + point, sizeof(txt) - point, "TC%i=%02X ", i, tx); point += 7; } if(ATR_GetInterfaceByte(atr, i, ATR_INTERFACE_BYTE_TD, &tx) == ATR_OK) { snprintf((char *)txt + point, sizeof(txt) - point, "TD%i=%02X ", i, tx); point += 7; tx &= 0X0F; snprintf((char *)txt + point, sizeof(txt) - point, "(T%i)", tx); if(tx == 14) { OffersT[2] = 1; } else { OffersT[tx] = 1; } } else { snprintf((char *)txt + point, sizeof(txt) - point, "no TD%i means T0", i); OffersT[0] = 1; } rdr_log_dbg(reader, D_ATR, "%s", txt); } int32_t numprottype = 0; for(i = 0; i <= 2; i++) if(OffersT[i]) { numprottype ++; } rdr_log_dbg(reader, D_ATR, "%i protocol types detected. Historical bytes: %s", numprottype, cs_hexdump(1, atr->hb, atr->hbn, tmp, sizeof(tmp))); ATR_GetParameter(atr, ATR_PARAMETER_N, &(N)); ATR_GetProtocolType(atr, 1, &(reader->protocol_type)); // get protocol from TD1 unsigned char TA2; bool SpecificMode = (ATR_GetInterfaceByte(atr, 2, ATR_INTERFACE_BYTE_TA, &TA2) == ATR_OK); // if TA2 present, specific mode, else negotiable mode if(SpecificMode) { reader->protocol_type = TA2 & 0x0F; if((TA2 & 0x10) != 0x10) // bit 5 set to 0 means F and D explicitly defined in interface characters { unsigned char TA1; if(ATR_GetInterfaceByte(atr, 1, ATR_INTERFACE_BYTE_TA, &TA1) == ATR_OK) { FI = TA1 >> 4; ATR_GetParameter(atr, ATR_PARAMETER_D, &(D)); } else { FI = ATR_DEFAULT_FI; D = ATR_DEFAULT_D; } } else { rdr_log(reader, "Specific mode: speed 'implicitly defined', not sure how to proceed, assuming default values"); FI = ATR_DEFAULT_FI; D = ATR_DEFAULT_D; } uint32_t F = atr_f_table[FI]; rdr_log_dbg(reader, D_ATR, "Specific mode: T%i, F=%d, D=%d, N=%d", reader->protocol_type, F, D, N); } else // negotiable mode { reader->read_timeout = 1000000; // in us bool PPS_success = 0; bool NeedsPTS = ((reader->protocol_type != ATR_PROTOCOL_TYPE_T14) && (numprottype > 1 || (atr->ib[0][ATR_INTERFACE_BYTE_TA].present == 1 && atr->ib[0][ATR_INTERFACE_BYTE_TA].value != 0x11) || N == 255)); //needs PTS according to old ISO 7816 if(NeedsPTS && deprecated == 0) { // PTSS PTS0 PTS1 PCK unsigned char req[6] = { 0xFF, 0x10, 0x00, 0x00 }; //we currently do not support PTS2, standard guardtimes or PTS3, //but spare 2 bytes in arrayif card responds with it req[1] = 0x10 | reader->protocol_type; //PTS0 always flags PTS1 to be sent always if(ATR_GetInterfaceByte(atr, 1, ATR_INTERFACE_BYTE_TA, &req[2]) != ATR_OK) //PTS1 { req[2] = 0x11; // defaults FI and DI to 1 } uint32_t len = 0; call(SetRightParity(reader)); ret = PPS_Exchange(reader, req, &len); if(ret == OK) { FI = req[2] >> 4; unsigned char DI = req[2] & 0x0F; D = atr_d_table[DI]; uint32_t F = atr_f_table[FI]; PPS_success = 1; rdr_log_dbg(reader, D_ATR, "PTS successful, selected protocol: T%i, F=%d, D=%d, N=%d", reader->protocol_type, F, D, N); } else { rdr_log_dump_dbg(reader, D_ATR, req, len, "PTS Failure, response:"); } } //When for SCI, T14 protocol, TA1 is obeyed, this goes OK for mosts devices, but somehow on DM7025 Sky S02 card goes wrong when setting ETU (ok on DM800/DM8000) if(!PPS_success) // last PPS not successful { unsigned char TA1; if(ATR_GetInterfaceByte(atr, 1, ATR_INTERFACE_BYTE_TA, &TA1) == ATR_OK) { FI = TA1 >> 4; ATR_GetParameter(atr, ATR_PARAMETER_D, &(D)); } else // do not obey TA1 { FI = ATR_DEFAULT_FI; D = ATR_DEFAULT_D; } if(NeedsPTS) { if((D == 32) || (D == 12) || (D == 20)) //those values were RFU in old table { D = 0; // viaccess cards that fail PTS need this } } uint32_t F = atr_f_table[FI]; rdr_log_dbg(reader, D_ATR, "No PTS %s, selected protocol T%i, F=%d, D=%d, N=%d", NeedsPTS ? "happened" : "needed", reader->protocol_type, F, D, N); } }//end negotiable mode //make sure no zero values uint32_t F = atr_f_table[FI]; if(!F) { FI = ATR_DEFAULT_FI; rdr_log(reader, "Warning: F=0 is invalid, forcing FI=%d", FI); } if(!D) { D = ATR_DEFAULT_D; rdr_log(reader, "Warning: D=0 is invalid, forcing D=%d", D); } rdr_log_dbg(reader, D_ATR, "Init card protocol T%i, FI=%d, F=%d, D=%d, N=%d", reader->protocol_type, FI, F, D, N); if(deprecated == 0) { return InitCard(reader, atr, FI, D, N, deprecated); } else { return InitCard(reader, atr, ATR_DEFAULT_FI, ATR_DEFAULT_D, N, deprecated); } } static int32_t PPS_Exchange(struct s_reader *reader, unsigned char *params, uint32_t *length) { const struct s_cardreader *crdr_ops = reader->crdr; if (!crdr_ops) return ERROR; unsigned char confirm[PPS_MAX_LENGTH]; uint32_t len_request, len_confirm; char tmp[128]; int32_t ret; len_request = PPS_GetLength(params); params[len_request - 1] = PPS_GetPCK(params, len_request - 1); rdr_log_dbg(reader, D_IFD, "PTS: Sending request: %s", cs_hexdump(1, params, len_request, tmp, sizeof(tmp))); if(crdr_ops->set_protocol) { ret = crdr_ops->set_protocol(reader, params, length, len_request); return ret; } // Send PPS request call(ICC_Async_Transmit(reader, len_request, len_request, params, 0, 1000000)); // Get PPS confirm call(ICC_Async_Receive(reader, 2, confirm, 0, 1000000)); len_confirm = PPS_GetLength(confirm); call(ICC_Async_Receive(reader, len_confirm - 2, confirm + 2, 0, 1000000)); rdr_log_dbg(reader, D_IFD, "PTS: Receiving confirm: %s", cs_hexdump(1, confirm, len_confirm, tmp, sizeof(tmp))); if((len_request != len_confirm) || (memcmp(params, confirm, len_request))) { ret = ERROR; } else { ret = OK; } // Copy PPS handshake memcpy(params, confirm, len_confirm); (*length) = len_confirm; return ret; } static uint32_t PPS_GetLength(unsigned char *block) { uint32_t length = 3; if(PPS_HAS_PPS1(block)) { length++; } if(PPS_HAS_PPS2(block)) { length++; } if(PPS_HAS_PPS3(block)) { length++; } return length; } static uint32_t ETU_to_us(struct s_reader *reader, uint32_t ETU) { return (uint32_t)((double) ETU * reader->worketu); // in us } static int32_t ICC_Async_SetParity(struct s_reader *reader, uint16_t parity) { const struct s_cardreader *crdr_ops = reader->crdr; if (!crdr_ops) return ERROR; if(crdr_ops->set_parity) { rdr_log_dbg(reader, D_IFD, "Setting right parity"); call(crdr_ops->set_parity(reader, parity)); } return OK; } static int32_t SetRightParity(struct s_reader *reader) { const struct s_cardreader *crdr_ops = reader->crdr; if (!crdr_ops) return ERROR; //set right parity uint16_t parity = PARITY_EVEN; if(reader->convention == ATR_CONVENTION_INVERSE) { parity = PARITY_ODD; } else if(reader->protocol_type == ATR_PROTOCOL_TYPE_T14) { parity = PARITY_NONE; } call(ICC_Async_SetParity(reader, parity)); if(crdr_ops->flush && reader->crdr_flush) { IO_Serial_Flush(reader); } return OK; } static int32_t InitCard(struct s_reader *reader, ATR *atr, unsigned char FI, uint32_t D, unsigned char N, uint16_t deprecated) { const struct s_cardreader *crdr_ops = reader->crdr; if (!crdr_ops) return ERROR; uint32_t I, F, Fi, BGT = 0, edc, GT = 0, WWT = 0, EGT = 0; unsigned char wi = 0; // set the amps and the volts according to ATR if(ATR_GetParameter(atr, ATR_PARAMETER_I, &I) != ATR_OK) { I = 0; } tempfi = FI; // set clock speed to max if internal reader if(crdr_ops->max_clock_speed == 1 && reader->typ == R_INTERNAL) { if(reader->autospeed == 1) //no overclocking { reader->mhz = atr_fs_table[FI] / 10000; // we are going to clock the card to this nominal frequency } if(reader->cardmhz > 2000 && reader->autospeed == 1) // -1 replaced by autospeed parameter is magic number pll internal reader set cardmhz according to optimal atr speed { reader->mhz = atr_fs_table[FI] / 10000 ; if((!strncmp(boxtype_get(), "vu", 2 ))||(boxtype_is("ini-8000am"))) { reader->mhz = 450; } } } if(reader->cardmhz > 2000) { reader->divider = 0; // reset pll divider so divider will be set calculated again. ICC_Async_GetPLL_Divider(reader); // calculate pll divider for target cardmhz. } Fi = atr_f_table[FI]; // get the frequency divider also called clock rate conversion factor if(crdr_ops->set_baudrate) { reader->current_baudrate = DEFAULT_BAUDRATE; if(deprecated == 0) { if(reader->protocol_type != ATR_PROTOCOL_TYPE_T14) // dont switch for T14 { uint32_t baud_temp = (double)D * ICC_Async_GetClockRate(reader->cardmhz) / (double)Fi; uint32_t baud_temp2 = (double)D * ICC_Async_GetClockRate(reader->mhz) / (double)Fi; rdr_log(reader, "Setting baudrate to %d bps", baud_temp2); // set_baudrate() increases/decreases baud_temp to baud_temp2 in case of over/underclocking call(crdr_ops->set_baudrate(reader, baud_temp)); reader->current_baudrate = baud_temp2; } } } if(reader->cardmhz > 2000 && reader->typ == R_INTERNAL) { F = reader->mhz; // for PLL based internal readers } else { if (reader->typ == R_SMART || is_smargo_reader(reader)) { if (reader->autospeed == 1) { uint32_t Fsmart = atr_fs_table[FI]; reader->mhz = Fsmart/10000; if(reader->mhz >= 1600) { reader->mhz = 1600; } else if(reader->mhz >= 1200) { reader->mhz = 1200; } else if(reader->mhz >= 961) { reader->mhz = 961; } else if(reader->mhz >= 800) { reader->mhz = 800; } else if(reader->mhz >= 686) { reader->mhz = 686; } else if(reader->mhz >= 600) { reader->mhz = 600; } else if(reader->mhz >= 534) { reader->mhz = 534; } else if(reader->mhz >= 480) { reader->mhz = 534; } else if(reader->mhz >= 436) { reader->mhz = 436; } else if(reader->mhz >= 400) { reader->mhz = 400; } else if(reader->mhz >= 369) { reader->mhz = 369; } else if(reader->mhz >= 357) { reader->mhz = 369; // 357 not suported by smartreader } else if(reader->mhz >= 343) { reader->mhz = 343; } else { reader->mhz = 320; } } } F = reader->mhz; //all other readers } reader->worketu = (double)((double)(1 / (double)D) * ((double)Fi / (double)((double)F / 100))); rdr_log_dbg(reader, D_ATR, "Calculated work ETU is %.2f us reader mhz = %u", reader->worketu, reader->mhz); //set timings according to ATR reader->read_timeout = 0; reader->block_delay = 0; reader->char_delay = 0; switch(reader->protocol_type) { case ATR_PROTOCOL_TYPE_T0: case ATR_PROTOCOL_TYPE_T14: { /* Integer value WI = TC2, by default 10 */ #ifndef PROTOCOL_T0_USE_DEFAULT_TIMINGS if(ATR_GetInterfaceByte(atr, 2, ATR_INTERFACE_BYTE_TC, &(wi)) != ATR_OK) #endif wi = DEFAULT_WI; WWT = (uint32_t) 960 * D * wi; //in work ETU GT = 2; // standard guardtime GT += 1; // start bit GT += 8; // databits GT += 1; // parity bit if(N != 255) //add extra Guard Time by ATR { EGT += N; // T0 protocol, if TC1 = 255 then dont add extra guardtime } reader->CWT = 0; // T0 protocol doesnt have char waiting time (used to detect errors within 1 single block of data) reader->BWT = 0; // T0 protocol doesnt have block waiting time (used to detect unresponsive card, this is max time for starting a block answer) rdr_log_dbg(reader, D_ATR, "Protocol: T=%i, WWT=%u, Clockrate=%u", reader->protocol_type, WWT, F * 10000); reader->read_timeout = WWT; // Work waiting time used in T0 (max time to signal unresponsive card!) reader->char_delay = GT + EGT; // Character delay is used on T0 rdr_log_dbg(reader, D_ATR, "Setting timings: timeout=%u ETU, block_delay=%u ETU, char_delay=%u ETU", reader->read_timeout, reader->block_delay, reader->char_delay); break; } case ATR_PROTOCOL_TYPE_T1: { unsigned char ta, tb, tc, cwi, bwi; // Set IFSC if(ATR_GetInterfaceByte(atr, 3, ATR_INTERFACE_BYTE_TA, &ta) == ATR_NOT_FOUND) { reader->ifsc = DEFAULT_IFSC; } else if((ta != 0x00) && (ta != 0xFF)) { reader->ifsc = ta; } else { reader->ifsc = DEFAULT_IFSC; } // FIXME workaround for Smargo until native mode works if(reader->smargopatch == 1) { reader->ifsc = MIN(reader->ifsc, 28); } else // Towitoko and smartreaders dont allow IFSC > 251 { reader->ifsc = MIN(reader->ifsc, MAX_IFSC); } #ifndef PROTOCOL_T1_USE_DEFAULT_TIMINGS // Calculate CWI and BWI if(ATR_GetInterfaceByte(atr, 3, ATR_INTERFACE_BYTE_TB, &tb) == ATR_NOT_FOUND) { #endif cwi = DEFAULT_CWI; bwi = DEFAULT_BWI; #ifndef PROTOCOL_T1_USE_DEFAULT_TIMINGS } else { cwi = tb & 0x0F; bwi = tb >> 4; } #endif // Set CWT = 11+(2^CWI) work etu reader->CWT = (uint16_t) 11 + (1 << cwi); // in work ETU reader->BWT = (uint32_t) ((1<worketu) + 11; // BWT in work ETU BGT = 22L; // Block Guard Time in ETU used to interspace between block responses GT = 2; // standard guardtime GT += 1; // start bit GT += 8; // databits GT += 1; // parity bit if(N == 255) { GT -= 1; // special case, ATR says standard 2 etu guardtime is decreased by 1 (in ETU) EGT remains zero! } else { EGT += N; // ATR says add extra guardtime (in ETU) } // Set the error detection code type if(ATR_GetInterfaceByte(atr, 3, ATR_INTERFACE_BYTE_TC, &tc) == ATR_NOT_FOUND) { edc = EDC_LRC; } else { edc = tc & 0x01; } // Set initial send sequence (NS) reader->ns = 1; rdr_log_dbg(reader, D_ATR, "Protocol: T=%i: IFSC=%d, CWT=%d etu, BWT=%d etu, BGT=%d etu, EDC=%s, N=%d", reader->protocol_type, reader->ifsc, reader->CWT, reader->BWT, BGT, (edc == EDC_LRC) ? "LRC" : "CRC", N); reader->read_timeout = reader->BWT; reader->block_delay = BGT; reader->char_delay = GT + EGT; rdr_log_dbg(reader, D_ATR, "Setting timings: reader timeout=%u ETU, block_delay=%u ETU, char_delay=%u ETU", reader->read_timeout, reader->block_delay, reader->char_delay); break; } default: return ERROR; break; }//switch SetRightParity(reader); // some reader devices need to get set the right parity uint32_t ETU = Fi / D; if(atr->hbn >= 6 && !memcmp(atr->hb, "IRDETO", 6) && reader->protocol_type == ATR_PROTOCOL_TYPE_T14) { ETU = 0; reader->worketu *= 2; // overclocked T14 needs this otherwise high ecm reponses } struct s_cardreader_settings s = { .ETU = ETU, .EGT = EGT, .P = 5, .I = I, .F = Fi, .Fi = (uint16_t) Fi, .Ni = N, .D = D, .WWT = WWT, .BGT = BGT, }; if(crdr_ops->write_settings) { call(crdr_ops->write_settings(reader, &s)); } /* if(reader->typ == R_INTERNAL) { if(reader->cardmhz > 2000) { rdr_log(reader, "PLL Reader: ATR Fsmax is %i MHz, clocking card to %.2f Mhz (nearest possible mhz specified reader->mhz)", atr_fs_table[FI] / 1000000, (float) reader->mhz / 100); } else { rdr_log(reader, "ATR Fsmax is %i MHz, clocking card to %.2f (specified in reader->mhz)", atr_fs_table[FI] / 1000000, (float) reader->mhz / 100); } } else { if ((reader->typ == R_SMART) && (reader->autospeed == 1)) { rdr_log(reader, "ATR Fsmax is %i MHz, clocking card to ATR Fsmax for smartreader cardspeed of %.2f MHz (specified in reader->mhz)", atr_fs_table[FI] / 1000000, (float) reader->mhz / 100); } else { rdr_log(reader, "ATR Fsmax is %i MHz, clocking card to wanted user cardclock of %.2f MHz (specified in reader->mhz)",atr_fs_table[FI] / 1000000, (float) reader->mhz / 100); } } */ //Communicate to T1 card IFSD -> we use same as IFSC if(reader->protocol_type == ATR_PROTOCOL_TYPE_T1 && reader->ifsc != DEFAULT_IFSC && !crdr_ops->skip_setting_ifsc) { unsigned char rsp[CTA_RES_LEN]; uint16_t lr = 0; int32_t ret; unsigned char tmp[] = { 0x21, 0xC1, 0x01, 0x00, 0x00 }; tmp[3] = reader->ifsc; // Information Field size tmp[4] = reader->ifsc ^ 0xE1; ret = Protocol_T1_Command(reader, tmp, sizeof(tmp), rsp, &lr); if(ret != OK) { rdr_log(reader, "Warning: Card returned error on setting ifsd value to %d", reader->ifsc); } else { rdr_log_dbg(reader, D_ATR, "Card responded ok for ifsd request of %d", reader->ifsc); } } return OK; } static unsigned char PPS_GetPCK(unsigned char *block, uint32_t length) { unsigned char pck; uint32_t i; pck = block[0]; for(i = 1; i < length; i++) { pck ^= block[i]; } return pck; } #endif