Opened 8 months ago
Last modified 5 months ago
#4727 new enhancement
add conax CWPK pairing support to the official trunk
Reported by: | Pawel Maky | Owned by: | |
---|---|---|---|
Priority: | major | Component: | Card support |
Severity: | medium | Keywords: | |
Cc: | Sensitive: | no |
Description
Reason for enhancement
<to support conax cards with cwpk pairing, support cwpk aquired throgh the method desciped in http://www.security-explorations.com/materials/SRP-2018-02.zip>
Possible impacts on other features
<just a new feature>
Please add to the official trunk new feature for CONAX cwpk pairing.
There is a public mod for that, i attach it.
The feature requires:
- in globals.h
uint8_t cwpk_mod[16];
uint8_t cwpk_mod_length
- in oscam-config-reader.c
new procedure:
static void cwpkkey_fn(const char *token, char *value, void *setting, FILE *f)
{
struct s_reader *rdr = setting;
if(value)
{
int32_t len = strlen(value);
rdr_log(rdr, "CWPK config key length: %16X", len);
if(len == 0 len > 32) {
rdr->cwpk_mod_length = 0;
memset(rdr->cwpk_mod, 0, sizeof(rdr->cwpk_mod));
}
else
{
if(key_atob_l(value, rdr->cwpk_mod, len))
{
fprintf(stderr, "reader cwpkkey parse error, %s=%s\n", token, value);
rdr->cwpk_mod_length = 0;
memset(rdr->cwpk_mod, 0, sizeof(rdr->cwpk_mod));
}
else
{
rdr->cwpk_mod_length = len/2;
}
}
return;
}
int32_t len = rdr->cwpk_mod_length;
if(len > 0)
{
char tmp[len * 2 + 1];
fprintf_conf(f, "cwpkkey", "%s\n", cs_hexdump(0, rdr->cwpk_mod, len, tmp, sizeof(tmp)));
}
else if(cfg.http_full_cfg)
{ fprintf_conf(f, "cwpkkey", "\n"); }
}
DEF_OPT_FUNC("cwpkkey" , 0, cwpkkey_fn),
DEF_OPT_FUNC("deskey" , 0, deskey_fn),
- in reader-conax.c
#include "cscrypt/des.h"
static int32_t CWPK_CNX(struct s_reader *reader, uint8_t *msg, uint8_t *mod)
{
def_resp;
int32_t ret = 0;
char CWPK_a[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t CWp1[8];
uint8_t CWp2[8];
uint8_t CWs1[8];
uint8_t CWs2[8];
uint8_t key[24];
CWPK_a[0] = mod[3];
CWPK_a[1] = mod[2];
CWPK_a[2] = mod[1];
CWPK_a[3] = mod[0];
CWPK_a[4] = mod[7];
CWPK_a[5] = mod[6];
CWPK_a[6] = mod[5];
CWPK_a[7] = mod[4];
CWPK_a[8] = mod[11];
CWPK_a[9] = mod[10];
CWPK_a[10] = mod[9];
CWPK_a[11] = mod[8];
CWPK_a[12] = mod[15];
CWPK_a[13] = mod[14];
CWPK_a[14] = mod[13];
CWPK_a[15] = mod[12];
CWPK_a[16] = mod[3];
CWPK_a[17] = mod[2];
CWPK_a[18] = mod[1];
CWPK_a[19] = mod[0];
CWPK_a[20] = mod[7];
CWPK_a[21] = mod[6];
CWPK_a[22] = mod[5];
CWPK_a[23] = mod[4];
memcpy(key, &CWPK_a,0x18);
rdr_log(reader, "CONAX_CWPKPairing - CWPK: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", CWPK_a[0], CWPK_a[1], CWPK_a[2], CWPK_a[3], CWPK_a[4], CWPK_a[5], CWPK_a[6], CWPK_a[7], CWPK_a[8], CWPK_a[9], CWPK_a[10], CWPK_a[11], CWPK_a[12], CWPK_a[13], CWPK_a[14], CWPK_a[15],CWPK_a[16], CWPK_a[17], CWPK_a[18], CWPK_a[19], CWPK_a[20], CWPK_a[21], CWPK_a[22], CWPK_a[23]);
CWp1[0] = msg[7];
CWp1[1] = msg[8];
CWp1[2] = msg[9];
CWp1[3] = msg[10];
CWp1[4] = msg[11];
CWp1[5] = msg[12];
CWp1[6] = msg[13];
CWp1[7] = msg[14];
CWp2[0] = msg[22];
CWp2[1] = msg[23];
CWp2[2] = msg[24];
CWp2[3] = msg[25];
CWp2[4] = msg[26];
CWp2[5] = msg[27];
CWp2[6] = msg[28];
CWp2[7] = msg[29];
rdr_log(reader, "CONAX_CWPKPairing - Encrypted CW1: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", CWp1[0], CWp1[1], CWp1[2], CWp1[3], CWp1[4], CWp1[5], CWp1[6], CWp1[7]);
des_ecb3_decrypt(CWp1,key);
des_ecb3_decrypt(CWp2,key);
CWs1[0] = CWp1[4];
CWs1[1] = CWp1[5];
CWs1[2] = CWp1[6];
CWs1[3] = CWp1[7];
CWs1[4] = CWp1[0];
CWs1[5] = CWp1[1];
CWs1[6] = CWp1[2];
CWs1[7] = CWp1[3];
rdr_log(reader, "CONAX_CWPKPairing - Decrypted CW1 - switched: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", CWs1[0], CWs1[1], CWs1[2], CWs1[3], CWs1[4], CWs1[5], CWs1[6], CWs1[7]);
CWs2[0] = CWp2[4];
CWs2[1] = CWp2[5];
CWs2[2] = CWp2[6];
CWs2[3] = CWp2[7];
CWs2[4] = CWp2[0];
CWs2[5] = CWp2[1];
CWs2[6] = CWp2[2];
CWs2[7] = CWp2[3];
memcpy(&msg[7],CWs1,0x08);
memcpy(&msg[22],CWs2,0x08);
ret = 0;
return ret;
}
static uint8_t PairingECMRotation(struct s_reader *reader, const ECM_REQUEST *er, int32_t n)
{
uint8_t cta_res[CTA_RES_LEN] = { 0x00 };
uint8_t ins26[] = { 0xDD, 0x26, 0x00, 0x00, 0x03, 0x10, 0x01, 0x00 };
uint8_t ins26on[] = { 0xDD, 0x26, 0x00, 0x00, 0x04, 0x6c, 0x02, 0x10, 0x00 };
uint8_t cnxcurrecm = 0;
uint8_t anscwp = 0;
if( (0x0 != reader->rsa_mod[0] 0x0 != reader->cwpk_mod[0]) && n > 3 && 0x54 == er->ecm[n - 3] &&
0x02 == er->ecm[n - 2] &&
0x00 == er->ecm[n - 1])
{
cnxcurrecm = 1;
}
if((0 == reader->cnxlastecm) != (0 == cnxcurrecm))
{
if(0 == cnxcurrecm) not paired
{ ins26[7] = 0x30;
if (0x0 != reader->cwpk_mod[0]) { if(read_record(reader, ins26, ins26 + 5, cta_res) <= 0)
{ rdr_log(reader, "PairingECMRotation - ERROR"); } }
}
else
{
ins26[7] = 0x40;
if(read_record(reader, ins26, ins26 + 5, cta_res) <= 0)
{ rdr_log(reader, "PairingECMRotation - ERROR"); }
if (0x0 != reader->cwpk_mod[0]) { anscwp = read_record(reader, ins26on, ins26on + 5, cta_res);
rdr_log(reader, "CONAX_CWPKPairing Rotation res: %16X", anscwp);
} }
}
reader->cnxlastecm = cnxcurrecm;
return cnxcurrecm;
}
tatic int32_t conax_do_ecm(struct s_reader *reader, const ECM_REQUEST *er, struct s_ecm_answer *ea)
{
def_resp;
int32_t i, j, n, num_dw = 0, rc = 0;
uint8_t insA2[] = { 0xDD, 0xA2, 0x00, 0x00, 0x00 };
uint8_t insCA[] = { 0xDD, 0xCA, 0x00, 0x00, 0x00 };
uint8_t exp[] = { 0x01, 0x00, 0x01 };
uint8_t buf[256];
char ppp = 0x00;
if((n = check_sct_len(er->ecm, 3)) < 0)
{ return ERROR; }
if(0x0 != PairingECMRotation(reader, er, n))
{
if(0x0 != reader->rsa_mod[0]) {buf[2] = 2; ppp = 0x03;}
if(0x0 != reader->cwpk_mod[0]) {buf[2] = 4; ppp = 0x01;}
} card will answer with encrypted dw
else
{ buf[2] = 0; ppp = 0x02;}
memcpy(buf + 3, er->ecm, n);
insA2[4] = n + 3;
write_cmd(insA2, buf); write Header + ECM
while((cta_res[cta_lr - 2] == 0x98) && Antwort
((insCA[4] = cta_res[cta_lr - 1]) > 0) && (insCA[4] != 0xFF))
{
write_cmd(insCA, NULL); Codeword auslesen
if((cta_res[cta_lr - 2] == 0x98) ((cta_res[cta_lr - 2] == 0x90))) {
/*checks if answer is encrypted with RSA algo and decrypts it if needed*/
if(0x81 == cta_res[0] && 2 == cta_res[2] >> 5 && 0x03 == ppp) /*81 XX 5X*/
{
if(0x00 == cta_res[cta_lr - 1])
{ rc = RSA_CNX(reader, cta_res, reader->rsa_mod, exp, cta_lr, 64u, 3u); }
else
{ rc = -4; } /*card has no right to decode this channel*/
}
if(0x01 == ppp)
{
/*trying to decode using CWPK*/
rc = CWPK_CNX(reader, cta_res, reader->cwpk_mod);
}
if(0 == rc)
{
for(i = 0; i < cta_lr - 2 && num_dw < 2; i += cta_res[i + 1] + 2)
{
switch(cta_res[i])
{
case 0x25:
if((cta_res[i + 1] >= 0xD) && !((n = cta_res[i + 4]) & 0xFE))
{
rc |= (1 << n);
memcpy(ea->cw + (n << 3), cta_res + i + 7, 8);
++num_dw;
}
break;
case 0x31:
if((cta_res[i + 1] == 0x02 && cta_res[i + 2] == 0x00 && cta_res[i + 3] == 0x00) (cta_res[i + 1] == 0x02 && cta_res[i + 2] == 0x40 && cta_res[i + 3] == 0x00))
{ break; }
else if(strcmp(reader->pincode, "none"))
{
conax_send_pin(reader);
write_cmd(insA2, buf); write Header + ECM
while((cta_res[cta_lr - 2] == 0x98) && Antwort
((insCA[4] = cta_res[cta_lr - 1]) > 0) && (insCA[4] != 0xFF))
{
write_cmd(insCA, NULL); Codeword auslesen
if((cta_res[cta_lr - 2] == 0x98) ((cta_res[cta_lr - 2] == 0x90) && (!cta_res[cta_lr - 1])))
{
for(j = 0; j < cta_lr - 2; j += cta_res[j + 1] + 2)
{
if((cta_res[j] == 0x25) && access: is cw
(cta_res[j + 1] >= 0xD) && 0xD: 5 header + 8 cw
!((n = cta_res[j + 4]) & 0xFE)) cw idx must be 0 or 1
{
rc |= (1 << n);
memcpy(ea->cw + (n << 3), cta_res + j + 7, 8);
++num_dw;
}
}
}
}
}
break;
}
}
}
}
}
switch(rc)
{
case -1:
rdr_log(reader, "conax decode ECM problem - RSA key is probably faulty");
break;
case -2:
rdr_log(reader, "conax RSA pairing - wrong size of data");
break;
case -3:
rdr_log(reader, "conax RSA pairing- wrong size of data for second round");
/* fallthrough */
case -4:
rdr_log(reader, "card has no right to decode this channel");
break;
}
/* answer 9011 - conax smart card need reset */
if(2 <= cta_lr && 0x90 == cta_res[cta_lr - 2] && 0x11 == cta_res[cta_lr - 1])
{
rdr_log(reader, "conax card hangs - reset is required");
reader->card_status = UNKNOWN;
}
if(rc == 3)
{ return OK; }
else
{ return ERROR; }
}
Attachments (3)
Change History (9)
Changed 8 months ago by
Attachment: | oscam_conax_cwpk_mod_by_MusK.zip added |
---|
comment:1 Changed 8 months ago by
Component: | ! Please select... → Card support |
---|---|
Priority: | Please fill in → major |
Severity: | Please fill in → medium |
Changed 8 months ago by
Attachment: | reader-conax.c added |
---|
comment:2 Changed 8 months ago by
I attached updated reader-conax.c
It's just needed to add cwpkkey variable to the webif, and ready for the trunk.
The webif should respect that:
when cwpkkey is used for a reader, the rsakey should be disabled in reader.conf, and when rsakey is used, the cwpkkey should be disabled. Disable a variable by adding # before it.
Changed 6 months ago by
Attachment: | cwpk_patch_11523.diff added |
---|
Patvh attached against 11523. Maybe time to merge CWPK support
comment:4 Changed 6 months ago by
I'm search help for card starting. My contact: jsandman2870 at gmail.com
comment:5 Changed 6 months ago by
hello I offer 500 dollars if it works and my card conax 0B00 iksarsat2 Gmail
RSA card's bug fixed, warnings deleted