source: trunk/reader-dre.c

Last change on this file was 11478, checked in by Gorgone Impertinence, 11 months ago

big cleanup pack 4

  • Property svn:eol-style set to LF
File size: 32.4 KB
Line 
1#include "globals.h"
2#ifdef READER_DRE
3#include "cscrypt/des.h"
4#include "reader-common.h"
5#include "reader-dre-common.h"
6
7struct dre_data
8{
9    uint8_t provider;
10};
11
12#define OK_RESPONSE 0x61
13#define CMD_BYTE 0x59
14
15static uint8_t xor(const uint8_t *cmd, int32_t cmdlen)
16{
17    int32_t i;
18    uint8_t checksum = 0x00;
19    for(i = 0; i < cmdlen; i++)
20        { checksum ^= cmd[i]; }
21    return checksum;
22}
23
24static int8_t isValidDCW(uint8_t *dw)
25{
26    if (((dw[0] + dw[1] + dw[2]) & 0xFF) != dw[3])
27    {
28        return 0;
29    }
30    if (((dw[4] + dw[5] + dw[6]) & 0xFF) != dw[7])
31    {
32        return 0;
33    }
34    if (((dw[8] + dw[9] + dw[10]) & 0xFF) != dw[11])
35    {
36        return 0;
37    }
38    if (((dw[12] + dw[13] + dw[14]) & 0xFF) != dw[15])
39    {
40        return 0;
41    }
42    return 1;
43}
44
45static int32_t dre_command(struct s_reader *reader, const uint8_t *cmd, int32_t cmdlen, uint8_t *cta_res,
46                            uint16_t *p_cta_lr, uint8_t crypted, uint8_t keynum, uint8_t dre_v, uint8_t cmd_type)
47{
48    // attention: inputcommand will be changed!!!!
49    //answer will be in cta_res, length cta_lr ; returning 1 = no error, return ERROR = err
50
51    uint8_t startcmd[] = { 0x80, 0xFF, 0x10, 0x01, 0x05 }; // any command starts with this,
52    // last byte is nr of bytes of the command that will be sent
53    // after the startcmd
54    // response on startcmd+cmd: = { 0x61, 0x05 } // 0x61 = "OK", last byte is nr. of bytes card will send
55    uint8_t reqans[] = { 0x00, 0xC0, 0x00, 0x00, 0x08 }; // after command answer has to be requested,
56    // last byte must be nr. of bytes that card has reported to send
57    uint8_t command[256];
58    uint8_t checksum;
59    char tmp[256];
60    int32_t headerlen = sizeof(startcmd);
61
62    if(dre_v > 0)
63    {
64        startcmd[1] = 0;
65        startcmd[2] = crypted;
66        startcmd[3] = keynum;
67    }
68
69    startcmd[4] = cmdlen + 3 - cmd_type; // commandlength + type + len + checksum bytes
70    memcpy(command, startcmd, headerlen);
71    command[headerlen++] = cmd_type ? 0x86 : CMD_BYTE; // type
72    command[headerlen++] = cmdlen + (cmd_type == 1 ? 0 : 1); // len = command + 1 checksum byte
73    memcpy(command + headerlen, cmd, cmdlen);
74
75    if(!cmd_type)
76    {
77        checksum = ~xor(cmd, cmdlen);
78        //rdr_log_dbg(reader, D_READER, "Checksum: %02x", checksum);
79        cmdlen += headerlen;
80        command[cmdlen++] = checksum;
81    }
82    else cmdlen += headerlen;
83
84    reader_cmd2icc(reader, command, cmdlen, cta_res, p_cta_lr);
85
86    if((*p_cta_lr != 2) || (cta_res[0] != OK_RESPONSE))
87    {
88        rdr_log(reader, "command sent to card: %s", cs_hexdump(0, command, cmdlen, tmp, sizeof(tmp)));
89        rdr_log(reader, "unexpected answer from card: %s", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
90        return ERROR; // error
91    }
92
93    rdr_log_dbg(reader, D_READER, "command sent to card: %s", cs_hexdump(0, command, cmdlen, tmp, sizeof(tmp)));
94    rdr_log_dbg(reader, D_READER, "answer from card: %s", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
95
96    reqans[4] = cta_res[1]; // adapt length byte
97    reader_cmd2icc(reader, reqans, 5, cta_res, p_cta_lr);
98
99    if(cta_res[0] != CMD_BYTE)
100    {
101        rdr_log(reader, "unknown response: cta_res[0] expected to be %02x, is %02x", CMD_BYTE, cta_res[0]);
102        return ERROR;
103    }
104
105    if((cta_res[1] == 0x03) && (cta_res[2] == 0xe2))
106    {
107        switch(cta_res[3 + dre_v])
108        {
109            case 0xe1:
110                rdr_log(reader, "checksum error: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
111                break;
112
113            case 0xe2:
114                rdr_log(reader, "wrong cmd len: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
115                break;
116
117            case 0xe3:
118                rdr_log(reader, "illegal command: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
119                break;
120
121            case 0xe4:
122                rdr_log(reader, "wrong adress type: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
123                break;
124
125            case 0xe5:
126                rdr_log(reader, "wrong CMD param: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
127                break;
128
129            case 0xe6:
130                rdr_log(reader, "wrong UA: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
131                break;
132
133            case 0xe7:
134                rdr_log(reader, "wrong group: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
135                break;
136
137            case 0xe8:
138                rdr_log(reader, "wrong key num: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
139                break;
140
141            case 0xeb:
142                rdr_log(reader, "No key or subscribe: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
143                break;
144
145            case 0xec:
146                rdr_log(reader, "wrong signature: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
147                break;
148
149            case 0xed:
150                rdr_log(reader, "wrong provider: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
151                break;
152
153            case 0xef:
154                rdr_log(reader, "wrong GEO code: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
155                break;
156
157            default:
158                rdr_log_dbg(reader, D_READER, "unknown error: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
159                break;
160        }
161        return ERROR; // error
162    }
163
164    int32_t length_excl_leader = *p_cta_lr;
165
166    if((cta_res[*p_cta_lr - 2] == 0x90) && (cta_res[*p_cta_lr - 1] == 0x00))
167        { length_excl_leader -= 2; }
168
169    checksum = ~xor(cta_res + 2, length_excl_leader - 3);
170
171    if(cta_res[length_excl_leader - 1] != checksum)
172    {
173        rdr_log(reader, "checksum does not match, expected %02x received %02x:%s", checksum,
174                cta_res[length_excl_leader - 1], cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
175        return ERROR; // error
176    }
177    return OK;
178}
179
180#define dre_script(cmd, len, cmd_type, crypted, keynum) \
181    { \
182        dre_command(reader, cmd, len, cta_res, &cta_lr, crypted, keynum, crypted, cmd_type); \
183    }
184
185#define dre_cmd(cmd) \
186    { \
187        dre_command(reader, cmd, sizeof(cmd), cta_res, &cta_lr, 0, 0, 0, 0); \
188    }
189
190#define dre_cmd_c(cmd,crypted,keynum) \
191    { \
192        dre_command(reader, cmd, sizeof(cmd),cta_res,&cta_lr, crypted, keynum, 1, 0); \
193    }
194
195static int32_t dre_set_provider_info(struct s_reader *reader)
196{
197    def_resp;
198    int32_t i;
199    int subscr_cmd_len = 4;
200    uint8_t subscr[4]; // = { 0x59, 0x14 }; // subscriptions
201    uint8_t dates[] = { 0x5b, 0x00, 0x14 }; // validity dates
202    uint8_t subscr_len = 0, n = 0;
203    struct dre_data *csystem_data = reader->csystem_data;
204
205    cs_clear_entitlement(reader);
206
207    switch(csystem_data->provider)
208    {
209        case 0x02:
210        case 0x03:
211            subscr[0] = 0x84;
212            subscr[1] = 0;
213            subscr[2] = 0x5F;
214            subscr[3] = csystem_data->provider;
215            dates[0] = 0x85;
216            subscr_len = 0x5F;
217            break;
218
219        case 0x18:
220        case 0x19:
221        case 0x1A:
222            subscr[0] = 0x94;
223            subscr[1] = 0;
224            subscr[2] = 0x5F;
225            subscr[3] = csystem_data->provider;
226            dates[0] = 0x95;
227            subscr_len = 0x5F;
228            break;
229
230        default:
231            subscr[0] = 0x59;
232            subscr[1] = csystem_data->provider;
233            subscr_len = 0x20;
234            subscr_cmd_len = 2;
235    }
236
237chk_subscr:
238
239    if((dre_script(subscr, subscr_cmd_len, 0, 0, 0))) // ask subscription packages, returns error on 0x11 card
240    {
241        uint8_t pbm[subscr_len];
242        char tmp_dbg[subscr_len*2+1];
243        memcpy(pbm, cta_res + 3, cta_lr - 6);
244        rdr_log_dbg(reader, D_READER, "pbm: %s", cs_hexdump(0, pbm, subscr_len, tmp_dbg, sizeof(tmp_dbg)));
245
246        for(i = 0; i < subscr_len; i++)
247        {
248            if(pbm[i] != 0xff)
249            {
250                dates[1] = i;
251                dates[2] = csystem_data->provider;
252                dre_cmd(dates); // ask for validity dates
253
254                time_t start;
255                time_t end;
256                start = (cta_res[3] << 24) | (cta_res[4] << 16) | (cta_res[5] << 8) | cta_res[6];
257                end = (cta_res[7] << 24) | (cta_res[8] << 16) | (cta_res[9] << 8) | cta_res[10];
258
259                struct tm temp;
260
261                localtime_r(&start, &temp);
262                int32_t startyear = temp.tm_year + 1900;
263                int32_t startmonth = temp.tm_mon + 1;
264                int32_t startday = temp.tm_mday;
265                localtime_r(&end, &temp);
266                int32_t endyear = temp.tm_year + 1900;
267                int32_t endmonth = temp.tm_mon + 1;
268                int32_t endday = temp.tm_mday;
269                rdr_log(reader, "active package %i valid from %04i/%02i/%02i to %04i/%02i/%02i",
270                        i + n, startyear, startmonth, startday, endyear, endmonth, endday);
271                cs_add_entitlement(reader, reader->caid, b2ll(4, reader->prid[0]), 0, i + n, start, end, 5, 1);
272            }
273        }
274    }
275
276    if(subscr_len == 0x5F) // read second part subscription packages, for DRE3 and DRE4
277    {
278        subscr[1] = 0x5F;
279        subscr[2] = 0x21;
280        subscr_len = 0x21;
281        n = 0x5F;
282        goto chk_subscr;
283    }
284
285    return OK;
286}
287
288static void dre_read_ee(struct s_reader *reader, const char *path, uint8_t provid)
289{
290    def_resp;
291    int i, n;
292    uint8_t *ee = malloc(2048);
293    if(ee == NULL) return;
294
295    uint8_t drecmd43[] = { 0x80, 0x00, 0x00, 0x00, 0x05, 0x59, 0x03, 0x43, 0x11, 0xAD };
296    uint8_t drecmd45[] = { 0x45, 0x11 };
297
298    drecmd43[8] = drecmd45[1] = provid;
299    drecmd43[9] = ~xor(&drecmd43[7], 2);
300
301    for(i = 0; i < 8; i++)
302    {
303        for(n = 0; n < 8; n++)
304        {
305            reader_cmd2icc(reader, drecmd43, 10, cta_res, &cta_lr);
306
307            dre_cmd_c(drecmd45, n, i * 32);
308
309            if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
310            {
311                free(ee);
312                rdr_log(reader, "ERROR read ee.bin from card");
313                return;
314            }
315
316            memcpy(&ee[((n * 8) + i) * 32] ,&cta_res[2] ,32);
317
318        }
319    }
320
321    FILE *pFile = fopen(path, "wb");
322
323    if(pFile == NULL)
324    {
325        free(ee);
326        return ;
327    }
328
329    fwrite(ee, 2048, 1, pFile);
330    fclose(pFile);
331    free(ee);
332    rdr_log(reader, "ee.bin saved to %s", path);
333}
334/*
335static void cmd_test(struct s_reader *reader)
336{
337    def_resp;
338    int i;
339    uint8_t drecmd[] = { 0x00, 0x02 };
340    char tmp[64];
341
342    for(i = 0; i <= 0xFF; i++)
343    {
344        if(i == 0x45) continue;
345        drecmd[0] = i;
346        dre_cmd(drecmd);
347        if(cta_res[2] == 0xE2)
348        {
349            if(cta_res[3] != 0xE3) rdr_log(reader, "cmd %02X error %02X",i ,cta_res[3]);
350        }
351        else
352        {
353            rdr_log(reader, "cmd %02X answer %s",i ,cs_hexdump(0, cta_res, cta_res[1]+2, tmp, sizeof(tmp)));
354        }
355    }
356
357    uint8_t drecmd[64];
358
359    //memset(drecmd, 0, 64);
360    //drecmd[0] = 0x71;
361    for(i = 2; i <= 64; i++)
362    {
363        memset(drecmd, 0, 64);
364        drecmd[i-1] = 0x02;
365        drecmd[0] = 0x71;
366
367        dre_script(drecmd, i, 0, 0, 0);
368
369        if(cta_res[2] == 0xE2)
370        {
371            if((cta_res[3] != 0xE2) & (cta_res[3] != 0xED)) rdr_log(reader, "Len %02X error %02X",i ,cta_res[3]);
372            if((cta_res[3] & 0xF0) != 0xE0) rdr_log(reader, "Len %02X answer %s",i ,cs_hexdump(0, cta_res, cta_res[1]+2, tmp, sizeof(tmp)));
373        }
374        else
375        {
376            rdr_log(reader, "Len %02X answer %s",i ,cs_hexdump(0, cta_res, cta_res[1]+2, tmp, sizeof(tmp)));
377        }
378    }
379}
380*/
381static int32_t dre_card_init(struct s_reader *reader, ATR *newatr)
382{
383    get_atr;
384    def_resp;
385    uint8_t ua[] = { 0x43, 0x15 }; // get serial number (UA)
386    uint8_t providers[] = { 0x49, 0x15 }; // get providers
387    uint8_t cmd56[] = { 0x56, 0x00 };
388    int32_t i;
389    char *card;
390    char tmp[9];
391
392    if((atr[0] != 0x3b) || (atr[1] != 0x15) || (atr[2] != 0x11) || (atr[3] != 0x12) || (
393            ((atr[4] != 0x01) || (atr[5] != 0x01)) &&
394            ((atr[4] != 0xca) || (atr[5] != 0x07)) &&
395            ((atr[4] != 0xcb) || (atr[5] != 0x07)) &&
396            ((atr[4] != 0xcc) || (atr[5] != 0x07)) &&
397            ((atr[4] != 0xcd) || (atr[5] != 0x07))
398        ))
399        { return ERROR; }
400
401    if(!cs_malloc(&reader->csystem_data, sizeof(struct dre_data)))
402        { return ERROR; }
403    struct dre_data *csystem_data = reader->csystem_data;
404
405    csystem_data->provider = atr[6];
406    uint8_t checksum = xor(atr + 1, 6);
407
408    if(checksum != atr[7])
409        { rdr_log(reader, "warning: expected ATR checksum %02x, smartcard reports %02x", checksum, atr[7]); }
410
411    switch(atr[6])
412    {
413        case 0:
414            if(!(dre_cmd(cmd56))) { return ERROR; }
415            if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00)) { return ERROR; }
416
417            switch(cta_res[4])
418            {
419                case 0x02:
420                    card = "Tricolor Centr DRE3";
421                    reader->caid = 0x4ae1;
422                    break;
423
424                case 0x03:
425                    card = "Tricolor Syberia DRE3";
426                    reader->caid = 0x4ae1;
427                    break;
428
429                case 0x18:
430                case 0x19:
431                    card = "Tricolor Centr DRE4";
432                    reader->caid = 0x2710;
433                    break;
434
435                case 0x1A:
436                    card = "Tricolor Syberia DRE4";
437                    reader->caid = 0x2710;
438                    break;
439
440                default:
441                    return ERROR;
442            }
443            csystem_data->provider = cta_res[4];
444            providers[0] = 0x83;
445            break;
446
447        case 0x11:
448            card = "Tricolor Centr DRE2";
449            reader->caid = 0x4ae1;
450            break; // 59 type card = MSP (74 type = ATMEL)
451
452        case 0x12:
453            card = "Cable TV";
454            reader->caid = 0x4ae1; // TODO not sure about this one
455            break;
456
457        case 0x14:
458            card = "Tricolor Syberia DRE2";
459            reader->caid = 0x4ae1;
460            break; // 59 type card
461
462        case 0x15:
463            card = "Platforma HD / DW old";
464            reader->caid = 0x4ae1;
465            break; // 59 type card
466
467        default:
468            return ERROR;
469    }
470
471    memset(reader->prid, 0x00, 8);
472
473    if(atr[6] > 0)
474    {
475        reader->prid[0][3] = atr[6];
476    }
477    else
478    {
479        reader->prid[0][3] = csystem_data->provider;
480    }
481
482    uint8_t cmd54[] = { 0x54, 0x14 }; // geocode
483    cmd54[1] = csystem_data->provider;
484    uint8_t geocode = 0;
485
486    if((dre_cmd(cmd54))) // error would not be fatal, like on 0x11 cards
487        { geocode = cta_res[3]; }
488
489    providers[1] = csystem_data->provider;
490    if(!(dre_cmd(providers)))
491        { return ERROR; } // fatal error
492
493    if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
494        { return ERROR; }
495
496    uint8_t provname[128];
497
498    for(i = 0; ((i < cta_res[2] - 6) && (i < 128)); i++)
499    {
500        provname[i] = cta_res[6 + i];
501        if(provname[i] == 0x00)
502            { break; }
503    }
504
505    int32_t major_version = cta_res[3];
506    int32_t minor_version = cta_res[4];
507
508    ua[1] = csystem_data->provider;
509    dre_cmd(ua); // error would not be fatal
510
511    int32_t hexlength = cta_res[1] - 2; // discard first and last byte, last byte is always checksum, first is answer code
512
513    if(reader->force_ua)
514    {
515        rdr_log(reader, "WARNING!!! used UA from force_ua %08X", reader->force_ua);
516        memcpy(cta_res + 3, &reader->force_ua, 4);
517    }
518
519    reader->hexserial[0] = 0;
520    reader->hexserial[1] = 0;
521    memcpy(reader->hexserial + 2, cta_res + 3, hexlength);
522
523    int32_t low_dre_id, dre_chksum;
524    uint8_t buf[32];
525
526    if(major_version < 0x3)
527    {
528        low_dre_id = ((cta_res[4] << 16) | (cta_res[5] << 8) | cta_res[6]) - 48608;
529        dre_chksum = 0;
530        snprintf((char *)buf, sizeof(buf), "%i%i%08i", csystem_data->provider - 16, major_version + 1, low_dre_id);
531
532        for(i = 0; i < 32; i++)
533        {
534            if(buf[i] == 0x00)
535                { break; }
536            dre_chksum += buf[i] - 48;
537        }
538
539        if(major_version < 2)
540        {
541            reader->caid = 0x4ae0;
542            card = csystem_data->provider == 0x11 ? "Tricolor Centr DRE1" : "Tricolor Syberia DRE1";
543        }
544
545        rdr_log(reader, "type: DRE Crypt, caid: %04X, serial: {%s}, dre id: %i%i%i%08i, geocode %i, card: %s v%i.%i",
546                reader->caid, cs_hexdump(0, reader->hexserial + 2, 4, tmp, sizeof(tmp)), dre_chksum,
547                csystem_data->provider - 16, major_version + 1, low_dre_id, geocode, card, major_version, minor_version);
548    }
549    else
550    {
551        low_dre_id = ((cta_res[4] << 16) | (cta_res[5] << 8) | cta_res[6]);
552        dre_chksum = 0;
553        snprintf((char *)buf, sizeof(buf), "%i%i%08i", csystem_data->provider, major_version, low_dre_id);
554
555        for(i = 0; i < 32; i++)
556        {
557            if(buf[i] == 0x00)
558                { break; }
559            dre_chksum += buf[i] - 48;
560        }
561        rdr_log(reader, "type: DRE Crypt, caid: %04X, serial: {%s}, dre id: %i%03i%i%08i, geocode %i, card: %s v%i.%i",
562                reader->caid, cs_hexdump(0, reader->hexserial + 2, 4, tmp, sizeof(tmp)), dre_chksum, csystem_data->provider,
563                major_version, low_dre_id, geocode, card, major_version, minor_version);
564    }
565
566    rdr_log(reader, "Provider name:%s.", provname);
567
568
569    memset(reader->sa, 0, sizeof(reader->sa));
570    memcpy(reader->sa[0], reader->hexserial + 2, 1); // copy first byte of unique address also in shared address, because we dont know what it is...
571
572    rdr_log_sensitive(reader, "SA = %02X%02X%02X%02X, UA = {%s}", reader->sa[0][0], reader->sa[0][1], reader->sa[0][2],
573                    reader->sa[0][3], cs_hexdump(0, reader->hexserial + 2, 4, tmp, sizeof(tmp)));
574
575    reader->nprov = 1;
576
577    //cmd_test(reader);
578
579    // exec user script, wicardd format
580    if(reader->userscript != NULL)
581    {
582        uint8_t *usercmd = NULL;
583        int cmd_len;
584        int n;
585        char *tempbuf = malloc(2048);
586        trim2(reader->userscript);
587        FILE *pFile = fopen(reader->userscript, "rt");
588
589        if(pFile != NULL)
590        {
591            uint8_t ignoreProvid = 0;
592            uint8_t crypted = 0;
593            uint8_t cryptkey = 0;
594            do
595            {
596                tempbuf[0] = '\0';
597                if(usercmd != NULL) free(usercmd);
598
599                if(fgets(tempbuf, 2048, pFile) == NULL) continue;
600
601                if(strlen(tempbuf) < 10) continue;
602
603                trim2(tempbuf);
604
605                ignoreProvid = 0;
606                crypted = 0;
607                cryptkey = 0;
608
609                if(tempbuf[0] == '8' && tempbuf[1] == '6' && csystem_data->provider == 0x11) ignoreProvid = 1;
610                else if(strncmp(tempbuf ,"REG2" ,4) == 0)
611                {
612                    dre_read_ee(reader, &tempbuf[4] ,csystem_data->provider);
613                    continue;
614                }
615                else if(strncmp(tempbuf ,"CR" ,2) == 0)
616                {
617                    crypted = 1;
618                    cryptkey = ((tempbuf[2] - (tempbuf[2] > 0x39 ? 0x37:0x30)) << 4) + ((tempbuf[3] - (tempbuf[3] > 0x39 ? 0x37:0x30)) & 0xF);
619                }
620                else if(tempbuf[0] != '5' && tempbuf[1] != '9') continue;
621
622                strtoupper(tempbuf);
623
624                cmd_len = strlen(tempbuf) / 2 - 3 + ignoreProvid - (crypted * 2);
625                usercmd = malloc(cmd_len);
626
627                for(i = 0, n = 4 + (crypted * 4); i < cmd_len; i++, n += 2)
628                {
629                    usercmd[i] = ((tempbuf[n] - (tempbuf[n] > 0x39 ? 0x37 : 0x30)) << 4) + ((tempbuf[n + 1] - (tempbuf[n + 1] > 0x39 ? 0x37 : 0x30)) & 0xF);
630                }
631
632                /*if(usercmd[cmd_len-1] != csystem_data->provider && !ignoreProvid)
633                {
634                    rdr_log(reader, "Skip script: current provid %02X , script provid %02X", csystem_data->provider, usercmd[cmd_len-1]);
635                    continue;
636                }
637                */
638                rdr_log(reader, "User script: %s", tempbuf);
639
640                /*ret =*/
641
642                rdr_log(reader, "Script %s", (dre_script(usercmd, cmd_len, ignoreProvid, crypted, cryptkey)) ? "done" : "error");
643            }
644            while(!feof(pFile));
645        }
646        else
647        {
648            rdr_log(reader, "Can't open script file (%s)", reader->userscript);
649        }
650
651        //if(usercmd != NULL) free(usercmd);
652        if(tempbuf != NULL) free(tempbuf);
653    }
654
655    if(csystem_data->provider == 0x11)
656    {
657        memset(reader->prid[1], 0x00, 8);
658        reader->prid[1][3] = 0xFE;
659        reader->nprov = 2;
660    }
661
662    if(!dre_set_provider_info(reader))
663        { return ERROR; } // fatal error
664
665
666    rdr_log(reader, "ready for requests");
667    return OK;
668}
669
670static void DREover(struct s_reader *reader, const uint8_t *ECMdata, uint8_t *DW)
671{
672    uint32_t key_schedule[32];
673
674    if(reader->des_key_length < 128)
675    {
676        rdr_log(reader, "error: deskey is missing or too short");
677        return;
678    }
679
680    if(ECMdata[2] >= (43 + 4) && ECMdata[40] == 0x3A && ECMdata[41] == 0x4B)
681    {
682        des_set_key(&reader->des_key[(ECMdata[42] & 0x0F) * 8], key_schedule);
683
684        des(DW, key_schedule, 0); // even DW post-process
685        des(DW + 8, key_schedule, 0); // odd DW post-process
686    };
687};
688
689static int32_t dre_do_ecm(struct s_reader *reader, const ECM_REQUEST *er, struct s_ecm_answer *ea)
690{
691    def_resp;
692    uint16_t overcryptId;
693    uint8_t tmp[16];
694    char tmp_dbg[256];
695    struct dre_data *csystem_data = reader->csystem_data;
696    if(reader->caid == 0x4ae0)
697    {
698        uint8_t ecmcmd41[] = { 0x41,
699                               0x58, 0x1f, 0x00, // fixed part, dont change
700                               0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // 0x01 - 0x08: next key
701                               0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, // 0x11 - 0x18: current key
702                               0x3b, 0x59, 0x11 }; // 0x3b = keynumber, can be a value 56 ;; 0x59 number of package = 58+1 - Pay Package ;; 0x11 = provider
703
704        ecmcmd41[22] = csystem_data->provider;
705        memcpy(ecmcmd41 + 4, er->ecm + 8, 16);
706        ecmcmd41[20] = er->ecm[6]; // keynumber
707        ecmcmd41[21] = 0x58 + er->ecm[25]; // package number
708        rdr_log_dbg(reader, D_READER, "unused ECM info front:%s", cs_hexdump(0, er->ecm, 8, tmp_dbg, sizeof(tmp_dbg)));
709        rdr_log_dbg(reader, D_READER, "unused ECM info back:%s", cs_hexdump(0, er->ecm + 24, er->ecm[2] + 2 - 24, tmp_dbg, sizeof(tmp_dbg)));
710
711        if((dre_cmd(ecmcmd41))) // ecm request
712        {
713            if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
714                { return ERROR; } // exit if response is not 90 00
715            memcpy(ea->cw, cta_res + 11, 8);
716            memcpy(ea->cw + 8, cta_res + 3, 8);
717
718            return OK;
719        }
720    }
721    else if(reader->caid == 0x4ae1)
722    {
723        if(csystem_data->provider == 0x11 || csystem_data->provider == 0x14)
724        {
725            uint8_t ecmcmd51[] = { 0x51, 0x02, 0x56, 0x05, 0x00, 0x4A, 0xE3, // fixed header?
726                                   0x9C, 0xDA, // first three nibbles count up, fourth nibble counts down; all ECMs sent twice
727                                   0xC1, 0x71, 0x21, 0x06, 0xF0, 0x14, 0xA7, 0x0E, // next key?
728                                   0x89, 0xDA, 0xC9, 0xD7, 0xFD, 0xB9, 0x06, 0xFD, // current key?
729                                   0xD5, 0x1E, 0x2A, 0xA3, 0xB5, 0xA0, 0x82, 0x11, // key or signature?
730                                   0x14 }; // provider
731
732            memcpy(ecmcmd51 + 1, er->ecm + 5, 0x21);
733            rdr_log_dbg(reader, D_READER, "unused ECM info front:%s", cs_hexdump(0, er->ecm, 5, tmp_dbg, sizeof(tmp_dbg)));
734            rdr_log_dbg(reader, D_READER, "unused ECM info back:%s", cs_hexdump(0, er->ecm + 37, 4, tmp_dbg, sizeof(tmp_dbg)));
735            ecmcmd51[33] = csystem_data->provider; // no part of sig
736
737            if((dre_cmd(ecmcmd51))) // ecm request
738            {
739                if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
740                    { return ERROR; } // exit if response is not 90 00
741
742                if(er->ecm[2] >= 46 && er->ecm[43] == 1 && csystem_data->provider == 0x11)
743                {
744                    memcpy(tmp, cta_res + 11, 8);
745                    memcpy(tmp + 8, cta_res + 3, 8);
746                    overcryptId = b2i(2, &er->ecm[44]);
747                    rdr_log_dbg(reader, D_READER, "ICG ID: %04X", overcryptId);
748
749                    Drecrypt2OverCW(overcryptId,tmp);
750
751                    if(isValidDCW(tmp))
752                    {
753                        memcpy(ea->cw, tmp, 16);
754                        return OK;
755                    }
756                    return ERROR;
757                }
758
759                DREover(reader, er->ecm, cta_res + 3);
760
761                if(isValidDCW(cta_res + 3))
762                {
763                    memcpy(ea->cw, cta_res + 11, 8);
764                    memcpy(ea->cw + 8, cta_res + 3, 8);
765                    return OK;
766                }
767            }
768        }
769        else if((csystem_data->provider == 0x02 || csystem_data->provider == 0x03) && er->ecm[3] == 3)
770        {
771            // DRE 3
772
773            if (er->ecm[4] == 2)
774            {
775                memcpy(ea->cw, &er->ecm[42], 8);
776                memcpy(&ea->cw[8], &er->ecm[34], 8);
777                return OK;
778            }
779
780            uint8_t cmdlen;
781            uint8_t crypted = er->ecm[8] & 1;
782            uint8_t cryptkey = (er->ecm[8] & 6) >> 1;
783
784            if (crypted == 0)
785            {
786                cmdlen = 50;
787            }
788            else
789            {
790                cmdlen = 57;
791            }
792
793            uint8_t ecmcmd[cmdlen];
794
795            memcpy(ecmcmd, &er->ecm[17], cmdlen - 1);
796            ecmcmd[cmdlen - 1] = csystem_data->provider;
797
798            dre_cmd_c(ecmcmd, crypted, cryptkey);
799
800            if(cta_res[2] == 0xD2 && isValidDCW(cta_res + 3))
801            {
802                memcpy(ea->cw, cta_res + 11, 8);
803                memcpy(ea->cw + 8, cta_res + 3, 8);
804                return OK;
805            }
806        }
807    }
808    else if(reader->caid == 0x2710 && er->ecm[3] == 4)
809    {
810        // DRE 4
811
812        if (er->ecm[4] == 4)
813        {
814            memcpy(ea->cw, &er->ecm[22], 8);
815            memcpy(&ea->cw[8], &er->ecm[14], 8);
816            return OK;
817        }
818
819        uint8_t cmdlen;
820        uint8_t crypted = er->ecm[8] & 1;
821        uint8_t cryptkey = (er->ecm[8] & 6) >> 1;
822
823        if (crypted == 0)
824        {
825            cmdlen = 58;
826        }
827        else
828        {
829            cmdlen = 65;
830        }
831
832        uint8_t ecmcmd[cmdlen];
833
834        memcpy(ecmcmd, &er->ecm[9], cmdlen - 1);
835        ecmcmd[cmdlen - 1] = csystem_data->provider;
836
837        dre_cmd_c(ecmcmd, crypted, cryptkey);
838
839        if(cta_res[2] == 0xD2 && isValidDCW(cta_res + 3))
840        {
841            memcpy(ea->cw, cta_res + 11, 8);
842            memcpy(ea->cw + 8, cta_res + 3, 8);
843            return OK;
844        }
845    }
846    return ERROR;
847}
848
849static int32_t dre_do_emm(struct s_reader *reader, EMM_PACKET *ep)
850{
851    def_resp;
852    struct dre_data *csystem_data = reader->csystem_data;
853
854    if(reader->caid == 0x4ae1)
855    {
856        if(reader->caid != b2i(2, ep->caid)) return ERROR;
857
858        if(ep->type == UNIQUE && ep->emm[39] == 0x3d)
859        {
860            /* For new package activation. */
861            uint8_t emmcmd58[26];
862            emmcmd58[0] = 0x58;
863            memcpy(&emmcmd58[1], &ep->emm[40], 24);
864            emmcmd58[25] = csystem_data->provider;
865
866            if((dre_cmd(emmcmd58)))
867                if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
868                    { return ERROR; }
869        }
870        else if(ep->emm[0] == 0x86 && ep->emm[4] == 0x02 /*&& csystem_data->provider != 0x11*/)
871        {
872            uint8_t emmcmd52[0x3a];
873            emmcmd52[0] = 0x52;
874            int32_t i;
875            for(i = 0; i < 2; i++)
876            {
877                memcpy(emmcmd52 + 1, ep->emm + 5 + 32 + i * 56, 56);
878
879                // check for shared address
880                if(ep->emm[3] != reader->sa[0][0])
881                    { return OK; } // ignore, wrong address
882
883                emmcmd52[0x39] = csystem_data->provider;
884
885                if((dre_cmd(emmcmd52)))
886                    if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
887                        { return ERROR; } // exit if response is not 90 00
888            }
889        }
890        else if(ep->emm[0] == 0x86 && ep->emm[4] == 0x4D && csystem_data->provider == 0x11)
891        {
892            uint8_t emmcmd52[0x3a];
893
894            emmcmd52[0] = 0x52;
895            emmcmd52[1] = 0x01;
896            emmcmd52[2] = ep->emm[5];
897            emmcmd52[3] = 0x01;
898            emmcmd52[4] = ep->emm[3];
899            emmcmd52[5] = 0;
900            emmcmd52[6] = 0;
901            emmcmd52[7] = 0;
902            emmcmd52[9] = 0x01;
903            emmcmd52[10] = 0x01;
904            emmcmd52[11] = 0;
905            memcpy(emmcmd52 + 13, ep->emm + 0x5C, 4);
906            int32_t i;
907
908            for(i = 0; i < 2; i++)
909            {
910                emmcmd52[8] = ep->emm[0x61 + i * 0x29];
911                if(i == 0) emmcmd52[12] = ep->emm[0x60] == 0x56 ? 0x56 : 0x3B;
912                else emmcmd52[12] = ep->emm[0x60] == 0x56 ? 0x3B : 0x56;
913                memcpy(emmcmd52 + 0x11, ep->emm + 0x62 + i * 0x29, 40);
914
915                // check for shared address
916                if(ep->emm[3] != reader->sa[0][0])
917                    { return OK; } // ignore, wrong address
918
919                emmcmd52[0x39] = csystem_data->provider;
920
921                if((dre_cmd(emmcmd52)))
922                    if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
923                        { return ERROR; } // exit if response is not 90 00
924            }
925        }
926        else if (ep->emm[0] == 0x8c && (csystem_data->provider == 0x02 || csystem_data->provider == 0x03)) // dre3 group emm
927        {
928            if(ep->emm[3] != reader->sa[0][0])
929                { return OK; } // ignore, wrong address
930
931            uint8_t crypted = ep->emm[10];
932
933            if ((crypted & 1) == 1)
934            {
935                uint8_t emmcmd[0x49];
936
937                memcpy(emmcmd, &ep->emm[0x13], 0x48);
938
939                emmcmd[0x48] = csystem_data->provider;
940
941                dre_cmd_c(emmcmd, crypted & 1, (crypted & 6) >> 1);
942
943                if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
944                        { return ERROR; } //exit if response is not 90 00
945
946                memcpy(emmcmd, &ep->emm[0x5B], 0x48);
947
948                emmcmd[0x48] = csystem_data->provider;
949
950                dre_cmd_c(emmcmd, crypted & 1, (crypted & 6) >> 1);
951
952                if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
953                        { return ERROR; } //exit if response is not 90 00
954
955                return OK;
956            }
957            else
958            {
959                uint8_t emmcmd[0x42];
960
961                memcpy(emmcmd, &ep->emm[0x13], 0x41);
962
963                emmcmd[0x41] = csystem_data->provider;
964
965                dre_cmd_c(emmcmd, crypted & 1, (crypted & 6) >> 1);
966
967                if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
968                        { return ERROR; } // exit if response is not 90 00
969
970                memcpy(emmcmd, &ep->emm[0x5B], 0x41);
971
972                emmcmd[0x41] = csystem_data->provider;
973
974                dre_cmd_c(emmcmd, crypted & 1, (crypted & 6) >> 1);
975
976                if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
977                        { return ERROR; } // exit if response is not 90 00
978
979                return OK;
980            }
981        }
982        else if(ep->type == GLOBAL && ep->emm[0] == 0x91)
983        {
984            Drecrypt2OverEMM(ep->emm);
985            return OK;
986        }
987        else return OK;
988    }
989    else if(reader->caid == 0x2710)
990    {
991        // DRE 4
992        if(ep->type == UNIQUE)
993        {
994            uint16_t cmdlen;
995            uint8_t class, hlbUA, KEYindex;
996            int i, keycount;
997            uint8_t CMDtype = ep->emm[7];
998            uint16_t EMMlen = ep->emm[2] | ((ep->emm[1] & 0xF) << 8);
999            uint8_t cryptflag = ep->emm[10];
1000            uint8_t crypted = cryptflag & 1;
1001            uint8_t cryptkey = (cryptflag & 6) >> 1;
1002
1003            if (CMDtype == 0x61)
1004            {
1005                uint8_t emmcmd91[19];
1006
1007                emmcmd91[0] = 0x91;
1008                emmcmd91[1] = ep->emm[19];
1009                emmcmd91[2] = ep->emm[8];
1010                emmcmd91[3] = ep->emm[20];
1011                if(reader->force_ua) emmcmd91[3] += 2;
1012                memcpy(&emmcmd91[4], &reader->hexserial[2], 4);
1013                emmcmd91[8] = 0xF0;
1014                emmcmd91[17] = ep->emm[22];
1015                emmcmd91[18] = csystem_data->provider;
1016
1017                if ((EMMlen - 24) > 16)
1018                {
1019                    hlbUA = reader->hexserial[5] & 0xF;
1020
1021                    uint16_t keypos = cryptflag == 2 ? 17 : 9;
1022                    keycount = (EMMlen - 24) / keypos;
1023
1024                    for(i = 0; i <= keycount ;i++)
1025                    {
1026                        if (i == keycount) return OK;
1027                        if (hlbUA == (ep->emm[23 + (keypos * i)] & 0xF) ) break;
1028                    }
1029
1030                    keypos = 24 + (keypos * i);
1031
1032                    memcpy(&emmcmd91[9], &ep->emm[keypos], 8);
1033
1034                    if((dre_cmd(emmcmd91)))
1035                        if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00) || (cta_res[2] != 0xA2))
1036                            return ERROR; // exit if response is not 90 00
1037
1038                    if (cryptflag == 2)
1039                    {
1040                        if (emmcmd91[17] == 0x56) KEYindex = 0x3B;
1041                        else KEYindex = 0x56;
1042
1043                        keypos += 8;
1044                        memcpy(&emmcmd91[9], &ep->emm[keypos], 8);
1045                        emmcmd91[17] = KEYindex;
1046
1047                        dre_cmd(emmcmd91);
1048
1049                        if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00) || (cta_res[2] != 0xA2))
1050                            { return ERROR; } // exit if response is not 90 00
1051
1052                        return OK;
1053                    }
1054                }
1055                return ERROR;
1056            }
1057            else if (CMDtype == 0x62)
1058            {
1059                if (!memcmp(&reader->hexserial[2], &ep->emm[3], 4))
1060                {
1061                    if (crypted)
1062                    {
1063                        cmdlen = 49;
1064                    }
1065                    else
1066                    {
1067                        cmdlen = 42;
1068                    }
1069
1070                    uint8_t emmcmd92[cmdlen];
1071
1072                    memcpy(emmcmd92, &ep->emm[19], cmdlen - 1);
1073                    emmcmd92[cmdlen - 1] = csystem_data->provider;
1074
1075                    if (crypted)
1076                    {
1077                        dre_cmd_c(emmcmd92, crypted, cryptkey);
1078                    }
1079                    else
1080                    {
1081                        dre_cmd(emmcmd92);
1082                    }
1083
1084                    if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
1085                            { return ERROR; } // exit if response is not 90 00
1086
1087                    class = ep->emm[8];
1088
1089                    uint8_t emmcmd95[3];
1090
1091                    emmcmd95[0] = 0x95;
1092                    emmcmd95[1] = class;
1093                    emmcmd95[2] = csystem_data->provider;
1094
1095                    dre_cmd(emmcmd95);
1096
1097                    uint8_t emmcmd91[19];
1098
1099                    emmcmd91[0] = 0x91;
1100                    emmcmd91[1] = ep->emm[102];
1101                    emmcmd91[2] = ep->emm[8];
1102                    emmcmd91[3] = ep->emm[103];
1103                    if(reader->force_ua) emmcmd91[3] += 2;
1104                    memcpy(&emmcmd91[4], &reader->hexserial[2], 4);
1105                    emmcmd91[8] = ep->emm[104];
1106                    memcpy(&emmcmd91[9], &ep->emm[72], 8);
1107                    emmcmd91[17] = ep->emm[105];
1108                    emmcmd91[18] = csystem_data->provider;
1109
1110                    dre_cmd(emmcmd91);
1111
1112                    if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00) || (cta_res[2] != 0xA2) )
1113                        { return ERROR; } // exit if response is not 90 00
1114
1115                    if (emmcmd91[17] == 0x56) KEYindex = 0x3B;
1116                    else KEYindex = 0x56;
1117
1118                    memcpy(&emmcmd91[9], &ep->emm[86], 8);
1119                    emmcmd91[17] = KEYindex;
1120
1121                    dre_cmd(emmcmd91);
1122
1123                    if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
1124                        { return ERROR; } // exit if response is not 90 00
1125                }
1126                return OK;
1127            }
1128            else
1129            {
1130                if (memcmp(&reader->hexserial[2], &ep->emm[3], 4)) return OK;
1131
1132                if (CMDtype == 0x63)
1133                {
1134                    uint8_t emmcmdA5[7];
1135
1136                    emmcmdA5[0] = 0xA5;
1137                    emmcmdA5[1] = 0;
1138                    memcpy(&emmcmdA5[2], &reader->hexserial[2], 4);
1139                    emmcmdA5[6] = csystem_data->provider;
1140
1141                    dre_cmd(emmcmdA5);
1142
1143                    if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
1144                        { return ERROR; } //exit if response is not 90 00
1145                }
1146
1147                if (crypted) cmdlen = EMMlen - 19;
1148                else cmdlen = ep->emm[11] + 1;
1149
1150                uint8_t emmcmd[cmdlen];
1151
1152                memcpy(emmcmd, &ep->emm[19], cmdlen - 1);
1153                emmcmd[cmdlen - 1] = csystem_data->provider;
1154
1155                if(emmcmd[0] == 0x45)
1156                {
1157                    cs_log("TRICOLOR Send KILL command for your card");
1158                    return ERROR;
1159                }
1160
1161                dre_cmd_c(emmcmd, crypted, cryptkey);
1162
1163                if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
1164                    { return ERROR; } //exit if response is not 90 00
1165            }
1166            return OK;
1167        }
1168        return ERROR;
1169    }
1170    else if(reader->caid != 0x2710 && reader->caid != 0x4AE1)
1171    {
1172        uint8_t emmcmd42[] =
1173        {
1174            0x42, 0x85, 0x58, 0x01, 0xC8, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x0C, 0xBD, 0x7B, 0x07, 0x04, 0xC8,
1175            0x77, 0x31, 0x95, 0xF2, 0x30, 0xB7, 0xE9, 0xEE, 0x0F, 0x81, 0x39, 0x1C, 0x1F, 0xA9, 0x11, 0x3E,
1176            0xE5, 0x0E, 0x8E, 0x50, 0xA4, 0x31, 0xBB, 0x01, 0x00, 0xD6, 0xAF, 0x69, 0x60, 0x04, 0x70, 0x3A,
1177            0x91,
1178            0x56, 0x58, 0x11
1179        };
1180        int32_t i;
1181
1182        switch(ep->type)
1183        {
1184            case UNIQUE:
1185                for(i = 0; i < 2; i++)
1186                {
1187                    memcpy(emmcmd42 + 1, ep->emm + 42 + i * 49, 48);
1188                    emmcmd42[49] = ep->emm[i * 49 + 41]; // keynr
1189                    emmcmd42[50] = 0x58 + ep->emm[40]; // package nr
1190                    emmcmd42[51] = csystem_data->provider;
1191                    if((dre_cmd(emmcmd42)))
1192                    {
1193                        if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
1194                            { return ERROR; } // exit if response is not 90 00
1195                    }
1196                }
1197                break;
1198
1199            case SHARED:
1200            default:
1201                memcpy(emmcmd42 + 1, ep->emm + 6, 48);
1202                emmcmd42[51] = csystem_data->provider;
1203                //emmcmd42[50] = ecmcmd42[2]; // TODO package nr could also be fixed 0x58
1204                emmcmd42[50] = 0x58;
1205                emmcmd42[49] = ep->emm[5]; // keynr
1206
1207                /* response:
1208                59 05 A2 02 05 01 5B
1209                90 00 */
1210
1211                if((dre_cmd(emmcmd42))) // first emm request
1212                {
1213                    if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
1214                        { return ERROR; } // exit if response is not 90 00
1215
1216                    memcpy(emmcmd42 + 1, ep->emm + 55, 7); // TODO OR next two lines?
1217                    //memcpy (emmcmd42 + 1, ep->emm + 55, 7); // FIXME either I cant count or my EMM log contains errors
1218                    //memcpy (emmcmd42 + 8, ep->emm + 67, 41);
1219                    emmcmd42[51] = csystem_data->provider;
1220                    //emmcmd42[50] = ecmcmd42[2]; // TODO package nr could also be fixed 0x58
1221                    emmcmd42[50] = 0x58;
1222                    emmcmd42[49] = ep->emm[54]; // keynr
1223
1224                    if((dre_cmd(emmcmd42))) // second emm request
1225                    {
1226                        if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
1227                            { return ERROR; } // exit if response is not 90 00
1228                    }
1229                }
1230        }
1231        return OK;
1232    }
1233    return ERROR;
1234}
1235
1236static int32_t dre_card_info(struct s_reader *UNUSED(rdr))
1237{
1238    return OK;
1239}
1240
1241const struct s_cardsystem reader_dre =
1242{
1243    .desc           = "dre",
1244    .caids          = (uint16_t[]){ 0x4AE0, 0x4AE1, 0x7BE0, 0x7BE1, 0x2710, 0 },
1245    .do_emm         = dre_do_emm,
1246    .do_ecm         = dre_do_ecm,
1247    .card_info      = dre_card_info,
1248    .card_init      = dre_card_init,
1249    .get_emm_type   = dre_common_get_emm_type,
1250    .get_emm_filter = dre_common_get_emm_filter,
1251};
1252
1253#endif
Note: See TracBrowser for help on using the repository browser.