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:

  1. in globals.h

uint8_t cwpk_mod[16];
uint8_t cwpk_mod_length

  1. 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),

  1. 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; }

buf[0] = 0x14;
buf[1] = n + 1;

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)

oscam_conax_cwpk_mod_by_MusK.zip (1.5 MB) - added by Pawel Maky 8 months ago.
reader-conax.c (18.6 KB) - added by MusKCP 8 months ago.
RSA card's bug fixed, warnings deleted
cwpk_patch_11523.diff (7.2 KB) - added by Nimloth 6 months ago.
Patvh attached against 11523. Maybe time to merge CWPK support

Download all attachments as: .zip

Change History (9)

Changed 8 months ago by Pawel Maky

comment:1 Changed 8 months ago by Pawel Maky

Component: ! Please select...Card support
Priority: Please fill inmajor
Severity: Please fill inmedium

Changed 8 months ago by MusKCP

Attachment: reader-conax.c added

RSA card's bug fixed, warnings deleted

comment:2 Changed 8 months ago by MusKCP

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.

Last edited 8 months ago by MusKCP (previous) (diff)

comment:3 Changed 6 months ago by camara

Hi, I need you urgently how to contact contact thank you

Changed 6 months ago by Nimloth

Attachment: cwpk_patch_11523.diff added

Patvh attached against 11523. Maybe time to merge CWPK support

comment:4 Changed 6 months ago by m j

I'm search help for card starting. My contact: jsandman2870 at gmail.com

comment:5 in reply to:  description Changed 6 months ago by Daniel Alberto Cuñado

hello I offer 500 dollars if it works and my card conax 0B00 iksarsat2 Gmail

comment:6 Changed 5 months ago by Daniel Alberto Cuñado

1000 dollars I offer if they manage to make it work

Note: See TracTickets for help on using tickets.