source: trunk/reader-nagracak7.c @ 11429

Last change on this file since 11429 was 11429, checked in by felixka, 17 months ago

Nagra:

  • prepare code for Nagra Merlin HD03, HD04 support
  • no ks included
File size: 22.6 KB
Line 
1#include "globals.h"
2#include <math.h>
3#ifdef READER_NAGRA_MERLIN
4#include "cscrypt/bn.h"
5#include "cscrypt/idea.h"
6#include "cscrypt/sha256.h"
7#include "cscrypt/aescbc.h"
8#include "csctapi/icc_async.h"
9#include "oscam-time.h"
10#include "reader-common.h"
11#include "oscam-work.h"
12#include "cscrypt/des.h"
13#include "cscrypt/mdc2.h"
14#include "reader-nagracak7.h"
15
16const unsigned char exponent[] = {0x01, 0x00, 0x01};
17const unsigned char d00ff[]    = {0x00,0xff,0xff,0xFF};
18const unsigned char irdid[]    = {0x64,0x65,0x6D,0x6F};
19const unsigned char data1[]    = {0x00,0x00,0x00,0x01};
20
21struct nagra_data
22{
23    IDEA_KEY_SCHEDULE ksSession;
24    int8_t      is_pure_nagra;
25    int8_t      is_tiger;
26    int8_t      is_n3_na;
27    int8_t      has_dt08;
28    int8_t      swapCW;
29    uint8_t     ExpiryDate[2];
30    uint8_t     ActivationDate[2];
31    uint8_t     plainDT08RSA[64];
32    uint8_t     IdeaCamKey[16];
33    uint8_t     sessi[16];
34    uint8_t     signature[8];
35    uint8_t     cam_state[3];
36    uint32_t    Date_ird;
37    uint32_t    Provider_ID_tiers;
38    uint16_t    tiers;
39    uint32_t    Expire_date_tiers_2;
40    uint32_t    Begin_date_tiers_2;
41    uint16_t    tiers_2;
42    int32_t     num_records;
43};
44
45// Datatypes
46#define IRDINFO     0x03
47#define TIERS       0x0C
48#define SYSID       0x05
49#define allproviders    0x06
50
51#define SYSTEM_NAGRA    0x1800
52#define SYSTEM_MASK 0xFF00
53
54static time_t tier_date(uint64_t date, char *buf, int32_t l)
55{
56    time_t ut = +694224000L + (date>>1);
57    if(buf){
58        struct tm t;
59        cs_gmtime_r(&ut, &t);
60        snprintf(buf, l, "%04d/%02d/%02d", t.tm_year + 1900, t.tm_mon + 1, t.tm_mday);
61    }
62    return ut;
63}
64
65void rsa_decrypt(unsigned char *edata50, int len,unsigned char *out, unsigned char *key, int keylen)
66{
67    BN_CTX *ctx0 = BN_CTX_new();
68#ifdef WITH_LIBCRYPTO
69    BN_CTX_start(ctx0);
70#endif
71    BIGNUM *bnN0 = BN_CTX_get(ctx0);
72    BIGNUM *bnE0 = BN_CTX_get(ctx0);
73    BIGNUM *bnCT0 = BN_CTX_get(ctx0);
74    BIGNUM *bnPT0 = BN_CTX_get(ctx0);
75    BN_bin2bn(&key[0], keylen, bnN0);
76    BN_bin2bn(exponent, 0x03, bnE0);
77    BN_bin2bn(&edata50[0], len, bnCT0);
78    BN_mod_exp(bnPT0, bnCT0, bnE0, bnN0, ctx0);
79    memset(out,0x00,len);
80    BN_bn2bin(bnPT0, out+ (len- BN_num_bytes(bnPT0)));
81    BN_CTX_end(ctx0);
82    BN_CTX_free(ctx0);
83}
84
85static void addProvider(struct s_reader *reader, unsigned char *cta_res)
86{
87    int32_t i;
88    int32_t toadd = 1;
89    for(i = 0; i < reader->nprov; i++){
90        if((cta_res[19] == reader->prid[i][2]) && (cta_res[20] == reader->prid[i][3])){
91            toadd = 0;
92        }
93    }
94    if(toadd){
95        reader->prid[reader->nprov][0] = 0;
96        reader->prid[reader->nprov][1] = 0;
97        reader->prid[reader->nprov][2] = cta_res[19];
98        reader->prid[reader->nprov][3] = cta_res[20];
99        memcpy(reader->sa[reader->nprov], reader->sa[0], 4);
100        reader->nprov += 1;
101    }
102}
103
104typedef struct{
105    uint32_t    Expire_date_tiers;
106    uint32_t    Begin_date_tiers;
107    uint16_t    tiers;
108    int32_t     num_records;
109    uint32_t    Provider_ID_tiers;
110} tiers_rec;
111
112static int32_t ParseDataType(struct s_reader *reader, unsigned char dt, unsigned char *cta_res, uint16_t cta_lr)
113{
114    struct nagra_data *csystem_data = reader->csystem_data;
115    char ds[20], de[16];
116    IDEA_KEY_SCHEDULE ks;
117    switch(dt)
118    {
119
120    case TIERS:
121        if((cta_res[13] >= 0x20) && (cta_lr != 0x10))
122        {
123            uint16_t chid = csystem_data->tiers;
124            if(reader->caid==0x1860 || reader->caid == 0x1830 || reader->caid == 0x1843)
125            {
126                int32_t id = b2i(2,cta_res +19);
127                csystem_data->tiers = b2i(2,cta_res +23);
128                rdr_log_dbg(reader, D_READER, "Provid : %04X", id);
129                rdr_log_dbg(reader, D_READER, "ID : %04X", chid);
130                cs_add_entitlement(
131                            reader,
132                            reader->caid,
133                            id,
134                            chid,
135                            0,
136                            tier_date(b2ll(4, cta_res + 42)-0x7f7, ds, 15), // noch nicht richtig
137                            tier_date(b2ll(4, cta_res + 28)-0x7f7, de, 15),
138                            4,
139                            1);
140
141                rdr_log(reader, "|%04X|%04X    |%s  |%s  |", id, chid, ds, de);
142                addProvider(reader, cta_res);
143            }
144            if(reader->caid==0x186A || reader->caid == 0x1882 )
145            {
146                int32_t id = (cta_res[19] * 256) | cta_res[20];
147                cs_add_entitlement(
148                            reader,
149                            reader->caid,
150                            id,
151                            chid,
152                            0,
153                            tier_date(b2ll(4, cta_res + 0x35)-0x7f7, ds, 15),
154                            tier_date(b2ll(4, cta_res + 0x27)-0x7f7, de, 15),
155                            4,
156                            1);
157
158                rdr_log(reader, "|%04X|%04X    |%s  |%s  |", id, chid, ds, de);
159                addProvider(reader, cta_res);
160            }
161        }
162        break;
163
164    //case 0x03:
165    case IRDINFO:
166        if(cta_res[13] == 0x4D || cta_res[13] == 0x50){
167            rdr_log_dump_dbg(reader, D_READER, cta_res+19, 2, "Provider ID :");
168            reader->card_valid_to=tier_date(b2ll(4, cta_res + 22)-0x7f7, ds, 15);
169        }
170        break;
171
172    case 0x02:
173        reader->prid[0][0]=cta_res[17];
174        reader->prid[0][1]=cta_res[18];
175        reader->prid[0][2]=cta_res[19];
176        reader->prid[0][3]=cta_res[20];
177
178        reader->prid[1][0] = 0x00;
179        reader->prid[1][1] = 0x00;
180        reader->prid[1][2] = 0x00;
181        reader->prid[1][3] = 0x00;
182        memcpy(reader->sa[1], reader->sa[0], 4);
183        reader->nprov += 1;
184        reader->caid = (SYSTEM_NAGRA | cta_res[25]);
185        break;
186
187    //case 0x05:
188    case SYSID:
189        memcpy(reader->edata,cta_res+26,0x70);
190        reader->dt5num=cta_res[20];
191        rsa_decrypt(reader->edata,0x70,reader->out,mod1,sizeof(mod1));
192        if(reader->dt5num==0x00)
193        {
194            memcpy(reader->kdt05_00,&reader->out[18],0x5C+2);
195            memcpy(&reader->kdt05_00[0x5C+2],cta_res+26+0x70,6);
196            memcpy(reader->ideakey1,reader->out,16);
197            memcpy(reader->block3,cta_res+26+0x70+6,8);
198            idea_set_encrypt_key(reader->ideakey1, &ks);
199            memset(reader->v, 0, sizeof(reader->v));
200            idea_cbc_encrypt(reader->block3, reader->iout, 8, &ks, reader->v, IDEA_DECRYPT);
201            memcpy(&reader->kdt05_00[0x5C+2+6],reader->iout,8);
202            rdr_log_dump_dbg(reader, D_READER, reader->kdt05_00, sizeof(reader->kdt05_00), "DT05_00: ");
203        }
204        if(reader->dt5num==0x10)
205        {
206            memcpy(reader->kdt05_10,&reader->out[16],6*16);
207            memcpy(reader->ideakey1,reader->out,16);
208            memcpy(reader->block3,cta_res+26+0x70,8);
209            idea_set_encrypt_key(reader->ideakey1, &ks);
210            memset(reader->v, 0, sizeof(reader->v));
211            idea_cbc_encrypt(reader->block3, reader->iout, 8, &ks, reader->v, IDEA_DECRYPT);
212            memcpy(&reader->kdt05_10[6*16],reader->iout,8);
213            rdr_log_dump_dbg(reader, D_READER, reader->kdt05_10, sizeof(reader->kdt05_10), "DT05_10: ");
214        }
215        if(cta_res[8] != 0x07)
216        {
217            reader->prid[reader->nprov][0] = 0;
218            reader->prid[reader->nprov][1] = 0;
219            reader->prid[reader->nprov][2] = cta_res[19];
220            reader->prid[reader->nprov][3] = cta_res[20];
221        }
222        break;
223
224    default:
225        return OK;
226    }
227    return ERROR;
228}
229
230static int32_t CAS7do_cmd(struct s_reader *reader, unsigned char dt,unsigned char len,unsigned char *res, uint16_t *rlen,int32_t sub,unsigned char retlen)
231{
232    //unsigned char dtdata[0x10];
233    memset(reader->dtdata,0xCC,len);
234
235    reader->dtdata[7]=0x04;
236    reader->dtdata[8]=0x04;
237
238    reader->dtdata[ 9]=(sub>>16)&0xFF;
239    reader->dtdata[10]=(sub>>8)&0xFF;
240    reader->dtdata[11]=(sub)&0xFF;
241
242    reader->dtdata[12]=dt;
243
244    do_cas7_cmd(reader,res,rlen,reader->dtdata,sizeof(reader->dtdata),retlen);
245
246    return true;
247}
248
249static int32_t CAS7GetDataType(struct s_reader *reader, unsigned char dt)
250{
251    def_resp;
252
253    int32_t sub=0x00;
254    unsigned char retlen=0x10;
255    while(true)
256    {
257        CAS7do_cmd(reader,dt,0x10,cta_res,&cta_lr,sub,retlen);
258        // check auf 90 am ende ??
259
260        uint32_t newsub=(cta_res[9]<<16)+(cta_res[10]<<8)+(cta_res[11]);
261        if(newsub==0xFFFFFF)
262        {
263            break;
264        }
265
266        if(cta_res[12]==dt) // seqcounter check ??
267        {
268            unsigned char oretlen=retlen;
269            retlen=cta_res[13]+0x10+0x2;
270            while(retlen%0x10!=0x00)retlen++;
271
272            if(retlen==oretlen)
273            {
274                sub=newsub+1;
275                retlen=0x10;
276                ParseDataType(reader,dt,cta_res,cta_lr);
277            }
278        }
279        else
280        {
281            break;
282        }
283    }
284
285    return true;
286}
287
288void sub_6AD78(uint32_t *dinit) // gbox function
289{
290    uint32_t v0=(uint32_t)*dinit;
291    double f0;
292    f0=v0;
293    double f12=16807;
294    double f15=2147483647;
295    f12=f0*f12;
296    double v12;
297    v12=fmod(f12,f15);
298    *dinit=v12;
299}
300
301void calc_cas7_exponent(uint32_t *dinit, unsigned char *out, uint8_t  len)
302{
303    memset(out,0x00,len);
304
305    sub_6AD78(dinit);
306
307    int R4=0;
308    int R5=0;
309    while(true)
310    {
311        uint32_t R0=(uint32_t)*dinit;
312        int R3=R4+3;
313        R5+=4;
314        if(R3>len)break;
315
316        out[R5-1]=((R0    )&0xFF);
317        out[R5-2]=((R0>> 8)&0xFF);
318        out[R5-3]=((R0>>16)&0xFF);
319        out[R5-4]=((R0>>24)&0xFF);
320        R4+=4;
321        sub_6AD78(dinit);
322
323    }
324
325    uint32_t R0=(uint32_t)*dinit;
326    while(R4<len)
327    {
328        out[R4]=R0&0xFF;
329        R4++;
330        R0>>=8;
331    }
332
333    out[0]&=0x03;
334    out[0x10]|=0x01;
335
336}
337
338void CAS7_getCamKey(struct s_reader *reader)
339{
340    def_resp;
341    uint8_t cmd0e[] = {0xCC,0xCC,0xCC,0xCC,0x00,0x00,0x09,0x0E,0x83,0x00,0x00,0x00,0x00,0x00,0x64,0x65,0x6D,0x6F,0x34,0x11,0x9D,
342    0x7E,0xEE,0xCE,0x53,0x09,0x80,0xAE,0x6B,0x5A,0xEE,0x3A,0x41,0xCE,0x09,0x75,0xEF,0xA6,0xBF,0x1E,0x98,0x4F,
343    0xA4,0x11,0x6F,0x43,0xCA,0xCD,0xD0,0x6E,0x69,0xFA,0x25,0xC1,0xF9,0x11,0x8E,0x7A,0xD0,0x19,0xC0,0xEB,0x00,
344    0xC0,0x57,0x2A,0x40,0xB7,0xFF,0x8A,0xBB,0x25,0x21,0xD7,0x50,0xE7,0x35,0xA1,0x85,0xCD,0xA6,0xD3,0xDE,0xB3,
345    0x3D,0x16,0xD4,0x94,0x76,0x8A,0x82,0x8C,0x70,0x25,0xD4,0x00,0xD0,0x64,0x8C,0x26,0xB9,0x5F,0x44,0xFF,0x73,
346    0x70,0xAB,0x43,0xF5,0x68,0xA2,0xB1,0xB5,0x8A,0x8E,0x02,0x5F,0x96,0x06,0xA8,0xC3,0x4F,0x15,0xCD,0x99,0xC2,
347    0x69,0xB8,0x35,0x68,0x11,0x4C,0x84,0x3E,0x94,0x1E,0x00,0x08,0x00,0x00,0xCC,0xCC,0xCC,0xCC};
348    do_cas7_cmd(reader,cta_res,&cta_lr,cmd0e,sizeof(cmd0e),0x20);
349    reader->dword_83DBC= (cta_res[18]<<24);
350    reader->dword_83DBC+=(cta_res[19]<<16);
351    reader->dword_83DBC+=(cta_res[20]<< 8);
352    reader->dword_83DBC+=(cta_res[21]    );
353    calc_cas7_exponent(&reader->dword_83DBC,reader->cas7expo,0x11);
354    memcpy(reader->cardid,cta_res+14,4);
355    rdr_log_dump_dbg(reader, D_READER, reader->cardid, 0x04, "CardSerial: ");
356    memcpy(reader->hexserial + 2, reader->cardid,4);
357    memcpy(reader->sa[0],reader->cardid,2);
358    unsigned long datal=(cta_res[9]<<24)+(cta_res[10]<<16)+(cta_res[11]<<8)+(cta_res[12]);
359    datal++;
360    reader->data2[0]=(datal>>24)&0xFF;
361    reader->data2[1]=(datal>>16)&0xFF;
362    reader->data2[2]=(datal>> 8)&0xFF;
363    reader->data2[3]=(datal    )&0xFF;
364
365    BN_CTX *ctx0 = BN_CTX_new();
366#ifdef WITH_LIBCRYPTO
367    BN_CTX_start(ctx0);
368#endif
369    BIGNUM *bnN0 = BN_CTX_get(ctx0);
370    BIGNUM *bnE0 = BN_CTX_get(ctx0);
371    BIGNUM *bnCT0 = BN_CTX_get(ctx0);
372    BIGNUM *bnPT0 = BN_CTX_get(ctx0);
373    BN_bin2bn(&mod50[0], 0x50, bnN0);
374    BN_bin2bn(&reader->cas7expo[0], 0x11, bnE0);
375    BN_bin2bn(&data50[0], 0x50, bnCT0);
376    BN_mod_exp(bnPT0, bnCT0, bnE0, bnN0, ctx0);
377    memset(reader->data,0x00,sizeof(reader->data));
378    BN_bn2bin(bnPT0, reader->data+ (0x50- BN_num_bytes(bnPT0)));
379    BN_CTX_end(ctx0);
380    BN_CTX_free(ctx0);
381   
382    memcpy(&reader->step1[0],d00ff,4);
383    memcpy(&reader->step1[4],reader->data,0x50);
384    memcpy(&reader->step1[4+0x50],irdid,0x04);
385    memcpy(&reader->step1[4+4+0x50],data1,0x04);
386    memcpy(&reader->step1[4+4+4+0x50],reader->data2,0x04);
387
388    BN_CTX *ctx1 = BN_CTX_new();
389#ifdef WITH_LIBCRYPTO
390    BN_CTX_start(ctx1);
391#endif
392    BIGNUM *bnN1 = BN_CTX_get(ctx1);
393    BIGNUM *bnE1 = BN_CTX_get(ctx1);
394    BIGNUM *bnCT1 = BN_CTX_get(ctx1);
395    BIGNUM *bnPT1 = BN_CTX_get(ctx1);
396    BN_bin2bn(&key60[0], 0x60, bnN1);
397    BN_bin2bn(&exp60[0], 0x60, bnE1);
398    BN_bin2bn(&reader->step1[0], 0x60, bnCT1);
399    BN_mod_exp(bnPT1, bnCT1, bnE1, bnN1, ctx1);
400    BN_bn2bin(bnPT1, reader->data+ (0x60- BN_num_bytes(bnPT1)));
401    BN_CTX_end(ctx1);
402    BN_CTX_free(ctx1);
403
404    memcpy(&reader->step2[0],d00ff,4);
405    memcpy(&reader->step2[4],reader->cardid,4);
406    memcpy(&reader->step2[8],reader->data,0x60);
407
408    BN_CTX *ctx2 = BN_CTX_new();
409#ifdef WITH_LIBCRYPTO
410    BN_CTX_start(ctx2);
411#endif
412    BIGNUM *bnN2 = BN_CTX_get(ctx2);
413    BIGNUM *bnE2 = BN_CTX_get(ctx2);
414    BIGNUM *bnCT2 = BN_CTX_get(ctx2);
415    BIGNUM *bnPT2 = BN_CTX_get(ctx2);
416    BN_bin2bn(&reader->kdt05_10[0], 0x68, bnN2);
417    BN_bin2bn(&exponent[0], 3, bnE2);
418    BN_bin2bn(&reader->step2[0], 0x68, bnCT2);
419    BN_mod_exp(bnPT2, bnCT2, bnE2, bnN2, ctx2);
420    BN_bn2bin(bnPT2, reader->data+ (0x68- BN_num_bytes(bnPT2)));
421    BN_CTX_end(ctx2);
422    BN_CTX_free(ctx2);
423
424    memcpy(&reader->step3[0],d00ff,4);
425    memcpy(&reader->step3[4],reader->data,0x68);
426
427    BN_CTX *ctx3 = BN_CTX_new();
428#ifdef WITH_LIBCRYPTO
429    BN_CTX_start(ctx3);
430#endif
431    BIGNUM *bnN3 = BN_CTX_get(ctx3);
432    BIGNUM *bnE3 = BN_CTX_get(ctx3);
433    BIGNUM *bnCT3 = BN_CTX_get(ctx3);
434    BIGNUM *bnPT3 = BN_CTX_get(ctx3);
435    BN_bin2bn(&reader->kdt05_00[0], 0x6c, bnN3);
436    BN_bin2bn(&exponent[0], 3, bnE3);
437    BN_bin2bn(&reader->step3[0], 0x6c, bnCT3);
438    BN_mod_exp(bnPT3, bnCT3, bnE3, bnN3, ctx3);
439    BN_bn2bin(bnPT3, reader->data+ (0x6c- BN_num_bytes(bnPT3)));
440    BN_CTX_end(ctx3);
441    BN_CTX_free(ctx3);
442
443    uint8_t cmd03[] = {0xCC,0xCC,0xCC,0xCC, 0x00,0x00,0x0A,0x03,0x6C,
444    0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,
445    0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,
446    0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,
447    0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,
448    0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,
449    0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,
450    0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,
451    0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC };
452
453    memcpy(&cmd03[9],reader->data,0x6c);
454    do_cas7_cmd(reader,cta_res,&cta_lr,cmd03,sizeof(cmd03),0x90);
455    memcpy(reader->encrypted,&cta_res[10],0x68);
456
457    BN_CTX *ctx = BN_CTX_new();
458#ifdef WITH_LIBCRYPTO
459    BN_CTX_start(ctx);
460#endif
461    BIGNUM *bnN = BN_CTX_get(ctx);
462    BIGNUM *bnE = BN_CTX_get(ctx);
463    BIGNUM *bnCT = BN_CTX_get(ctx);
464    BIGNUM *bnPT = BN_CTX_get(ctx);
465    BN_bin2bn(&reader->kdt05_10[0], 104, bnN);
466    BN_bin2bn(&exponent[0], 3, bnE);
467    BN_bin2bn(&reader->encrypted[0], 104, bnCT);
468    BN_mod_exp(bnPT, bnCT, bnE, bnN, ctx);
469    memset(reader->result, 0, 104);
470    BN_bn2bin(bnPT, reader->result + (104 - BN_num_bytes(bnPT)));
471    BN_CTX_end(ctx);
472    BN_CTX_free(ctx);
473
474    //uchar stillencrypted[0x50];
475    memcpy(reader->stillencrypted,&reader->result[12],0x50);
476
477    //uchar resultrsa[0x50];
478    BN_CTX *ctxs = BN_CTX_new();
479#ifdef WITH_LIBCRYPTO
480    BN_CTX_start(ctxs);
481#endif
482    BIGNUM *bnNs  = BN_CTX_get(ctxs);
483    BIGNUM *bnEs  = BN_CTX_get(ctxs);
484    BIGNUM *bnCTs = BN_CTX_get(ctxs);
485    BIGNUM *bnPTs = BN_CTX_get(ctxs);
486    BN_bin2bn(&mod50[0], sizeof(mod50), bnNs);
487    BN_bin2bn(&reader->cas7expo[0], 0x11, bnEs);
488    BN_bin2bn(&reader->stillencrypted[0], 0x50, bnCTs);
489    BN_mod_exp(bnPTs, bnCTs, bnEs, bnNs, ctxs);
490    BN_bn2bin(bnPTs, reader->resultrsa + (0x50- BN_num_bytes(bnPTs)));
491    BN_CTX_end(ctxs);
492    BN_CTX_free(ctxs);
493
494    unsigned char mdc_hash[MDC2_DIGEST_LENGTH];
495    memset(mdc_hash,0x00,MDC2_DIGEST_LENGTH);
496
497    MDC2_CTX c;
498    MDC2_Init(&c);
499    MDC2_Update(&c, reader->resultrsa, sizeof(reader->resultrsa));
500    MDC2_Final(&(mdc_hash[0]), &c);
501
502    memcpy(&reader->cas7_aes_key[16],mdc_hash,16);
503    memcpy(reader->cas7_aes_key,mdc_hash,16);
504}
505
506static int32_t nagra7_card_init(struct s_reader *reader, ATR *newatr)
507{
508    get_atr;
509    int8_t is_pure_nagra = 0;
510    int8_t is_tiger = 0;
511    int8_t is_n3_na = 0;
512    memset(reader->irdId, 0xff, 4);
513    memset(reader->hexserial, 0, 6);
514    reader->cas7_seq=0x00;
515    cs_clear_entitlement(reader);
516    if(memcmp(atr + 11, "DNASP4", 6) == 0)
517    {
518        memcpy(reader->rom, atr + 11, 15);
519        rdr_log(reader,"Rom revision: %.15s", reader->rom);
520    }
521    else
522    {
523        return ERROR;
524    }
525
526    if(!reader->csystem_data)
527    {
528        if(!cs_malloc(&reader->csystem_data, sizeof(struct nagra_data)))
529        {
530            rdr_log(reader, "cs_malloc error");
531            return ERROR;
532        }
533    }
534    struct nagra_data *csystem_data = reader->csystem_data;
535    csystem_data->is_pure_nagra = is_pure_nagra;
536    csystem_data->is_tiger      = is_tiger;
537    csystem_data->is_n3_na      = is_n3_na;
538
539    reader->nprov = 1;
540    CAS7GetDataType(reader, 0x09);
541    CAS7GetDataType(reader, 0x05);
542    CAS7_getCamKey(reader);
543    CAS7GetDataType(reader, 0x09);
544    CAS7GetDataType(reader, 0x02); // sysid+caid
545    CAS7GetDataType(reader, 0x03);
546    return OK;
547}
548
549typedef struct
550{
551    char date1[11];
552    char date2[11];
553    uint8_t type;
554    uint16_t value;
555    uint16_t price;
556} ncmed_rec;
557
558static int32_t nagra7_card_info(struct s_reader *reader)
559{
560    int32_t i;
561    char tmp[64];
562
563    int crcdigits; // checksum digits
564    crcdigits = (((unsigned long long) b2ll(6, reader->hexserial + 2) % 2300) / 100 + ((unsigned long long) b2ll(6, reader->hexserial + 2)));
565    rdr_log(reader, "ROM:    %c %c %c %c %c %c %c %c", reader->rom[0], reader->rom[1], reader->rom[2], reader->rom[3], reader->rom[4], reader->rom[5], reader->rom[6], reader->rom[7]);
566    rdr_log(reader, "REV:    %c %c %c %c %c %c", reader->rom[9], reader->rom[10], reader->rom[11], reader->rom[12], reader->rom[13], reader->rom[14]);
567    //rdr_log_sensitive(reader, "SER:    {%s} (%llu-%i)", cs_hexdump(0, reader->hexserial + 2, 4, tmp, sizeof(tmp)),(unsigned long long) b2ll(4, reader->hexserial + 2), crcdigits);
568    rdr_log_sensitive(reader, "SER:    {%s}  {%llu}", cs_hexdump(0, reader->hexserial + 2, 4, tmp, sizeof(tmp)),(unsigned long long) b2ll(4, reader->hexserial + 2));
569    rdr_log_dbg(reader, D_READER, "checksum digits: %i", crcdigits);
570    rdr_log(reader, "CAID:   %04X", reader->caid);
571    rdr_log(reader, "Prv.ID: %s(sysid)", cs_hexdump(1, reader->prid[0], 4, tmp, sizeof(tmp)));
572
573    if (reader->irdId[0] == 0xFF && reader->irdId[1] == 0xFF && reader->irdId[2] == 0xFF && reader->irdId[3] == 0xFF)
574        {
575            rdr_log(reader, "IRD ID: FF FF FF FF");
576        } 
577    else 
578        {
579            rdr_log_sensitive(reader, "IRD ID: {%s}", cs_hexdump(1, reader->irdId, 4, tmp, sizeof(tmp)));
580        }
581
582    cs_clear_entitlement(reader); //reset the entitlements
583    rdr_log(reader, "-----------------------------------------");
584    rdr_log(reader, "|id  |tier    |valid from  |valid to    |");
585    rdr_log(reader, "+----+--------+------------+------------+");
586
587    CAS7GetDataType(reader, 0x0C);
588    rdr_log(reader, "-----------------------------------------");
589
590    CAS7GetDataType(reader, 0x06);
591    for(i = 1; i < reader->nprov; i++)
592    {
593        rdr_log(reader, "Prv.ID: %s", cs_hexdump(1, reader->prid[i], 4, tmp, sizeof(tmp)));
594    }
595    if (reader->caid)
596        {
597            rdr_log(reader, "ready for requests");
598        }
599   
600    return OK;
601}
602
603void nagra7_post_process(struct s_reader *reader)
604{
605    struct nagra_data *csystem_data = reader->csystem_data;
606    if((csystem_data->cam_state[0]&64)==64)
607    {
608        rdr_log(reader, "renew Session Key: CAS7");
609        CAS7_getCamKey(reader);
610    }
611}
612
613static int32_t nagra7_do_ecm(struct s_reader *reader, const ECM_REQUEST *er, struct s_ecm_answer *ea)
614{
615    def_resp;
616    struct nagra_data *csystem_data = reader->csystem_data;
617
618    uint8_t ecmreq[0xC0];
619    memset(ecmreq,0xCC,0xC0);
620
621    ecmreq[ 7]=0x05;
622    ecmreq[ 8]=0x8A;
623    ecmreq[ 9]=0x00;
624    ecmreq[10]=0x00;
625    ecmreq[11]=0x00;
626    ecmreq[12]=0x00;
627    ecmreq[13]=0x01;
628    memcpy(&ecmreq[14],er->ecm + 4, er->ecm[4]+1);
629
630    do_cas7_cmd(reader,cta_res,&cta_lr,ecmreq,sizeof(ecmreq),0xB0);
631    if(cta_res[cta_lr-2] != 0x90 && cta_res[cta_lr-1] != 0x00){
632        rdr_log(reader, "(ECM) Reader will be restart now cause: %02X %02X card answer!!!", cta_res[cta_lr-2], cta_res[cta_lr-1]);
633        reader->card_status = CARD_NEED_INIT;
634        add_job(reader->client, ACTION_READER_RESTART, NULL, 0);
635    }
636
637    if(cta_res[27]==0x5C)
638    {
639        uint8_t _cwe0[8];
640        uint8_t _cwe1[8];
641        int32_t i;
642        if (cta_res[78] == 0x01)
643        {
644            rdr_log (reader,"Swap dcw is at use !");  //; csystem_data->swapCW == 1;
645            memcpy(_cwe0,&cta_res[52],0x08);
646            memcpy(_cwe1,&cta_res[28],0x08);
647        }
648        else
649        {
650            memcpy(_cwe0,&cta_res[28],0x08);
651            memcpy(_cwe1,&cta_res[52],0x08);
652        }
653        if (array_has_nonzero_byte(_cwe_key, 128) > 0)
654        {
655            i = cta_res[24];
656            memcpy(_cwe_key, _cwe_key+(i*16), 16);
657            rdr_log_dump_dbg(reader, D_READER, _cwe_key, sizeof(_cwe_key), "Using CWPK-%d from config:",i);
658        }
659        _3DES(_cwe0,_cwe_key);
660        _3DES(_cwe1,_cwe_key);
661        int chkok=1;
662
663        if(((_cwe0[0]+_cwe0[1]+_cwe0[2])&0xFF)!=_cwe0[3])
664        {
665            chkok=0;
666            rdr_log_dbg(reader, D_READER, "CW0 checksum error [0]");
667        }
668        if(((_cwe0[4]+_cwe0[5]+_cwe0[6])&0xFF)!=_cwe0[7])
669        {
670            chkok=0;
671            rdr_log_dbg(reader, D_READER, "CW0 checksum error [1]");
672        }
673        if(((_cwe1[0]+_cwe1[1]+_cwe1[2])&0xFF)!=_cwe1[3])
674        {
675            chkok=0;
676            rdr_log_dbg(reader, D_READER, "CW1 checksum error [0]");
677        }
678        if(((_cwe1[4]+_cwe1[5]+_cwe1[6])&0xFF)!=_cwe1[7])
679        {
680            chkok=0;
681            rdr_log_dbg(reader, D_READER, "CW1 checksum error [1]");
682        }
683
684        csystem_data->cam_state[0]=cta_res[4];
685        if(chkok==1)
686        {
687            rdr_log_dbg(reader, D_READER, "CW Decrypt ok");
688            memcpy(ea->cw,_cwe0,0x08);
689            memcpy(ea->cw+8,_cwe1,0x08);
690            return OK;
691        }
692    }
693
694    return ERROR;
695}
696
697int32_t nagra7_get_emm_type(EMM_PACKET *ep, struct s_reader *rdr)  //returns 1 if shared emm matches SA, unique emm matches serial, or global or unknown
698{
699    switch(ep->emm[0])
700    {
701    case 0x83:
702    case 0x87:
703        memset(ep->hexserial, 0, 8);
704        ep->hexserial[0] = ep->emm[5];
705        ep->hexserial[1] = ep->emm[4];
706        ep->hexserial[2] = ep->emm[3];
707        if(ep->emm[7] == 0x10)
708        {
709            ep->type = SHARED;
710            return (!memcmp(rdr->hexserial + 2, ep->hexserial, 3));
711        }
712        else
713        {
714            ep->hexserial[3] = ep->emm[6];
715            ep->type = UNIQUE;
716            return (!memcmp(rdr->hexserial + 2, ep->hexserial, 4));
717        }
718    case 0x82:
719    case 0x84:
720        ep->type = GLOBAL;
721        return 1;
722    default:
723        ep->type = UNKNOWN;
724        return 1;
725    }
726}
727
728static int32_t nagra7_get_emm_filter(struct s_reader *rdr, struct s_csystem_emm_filter **emm_filters, unsigned int *filter_count)
729{
730    if(*emm_filters == NULL)
731    {
732        const unsigned int max_filter_count = 3;
733        if(!cs_malloc(emm_filters, max_filter_count * sizeof(struct s_csystem_emm_filter)))
734        {
735            return ERROR;
736        }
737
738        struct s_csystem_emm_filter *filters = *emm_filters;
739        *filter_count = 0;
740
741        int32_t idx = 0;
742
743        filters[idx].type = EMM_GLOBAL;
744        filters[idx].enabled   = 1;
745        filters[idx].filter[0] = 0x86;
746        filters[idx].mask[0]   = 0xF9;   // 0x82, 0x84 and 0x86
747        idx++;
748
749        filters[idx].type = EMM_SHARED;
750        filters[idx].enabled   = 1;
751        filters[idx].filter[0] = 0x87;
752        filters[idx].filter[1] = rdr->hexserial[4];
753        filters[idx].filter[2] = rdr->hexserial[3];
754        filters[idx].filter[3] = rdr->hexserial[2];
755        filters[idx].filter[4] = 0x00;
756        filters[idx].filter[5] = 0x10;
757        filters[idx].mask[0]   = 0xFB;   // 0x83 and 0x87
758        memset(&filters[idx].mask[1], 0xFF, 5);
759        idx++;
760
761        filters[idx].type = EMM_UNIQUE;
762        filters[idx].enabled   = 1;
763        filters[idx].filter[0] = 0x87;
764        filters[idx].filter[1] = rdr->hexserial[4];
765        filters[idx].filter[2] = rdr->hexserial[3];
766        filters[idx].filter[3] = rdr->hexserial[2];
767        filters[idx].filter[4] = rdr->hexserial[5];
768        filters[idx].filter[5] = 0x00;
769        filters[idx].mask[0]   = 0xFB;   // 0x83 and 0x87
770        memset(&filters[idx].mask[1], 0xFF, 5);
771        idx++;
772
773        *filter_count = idx;
774    }
775
776    return OK;
777}
778
779static int32_t nagra7_do_emm(struct s_reader *reader, EMM_PACKET *ep)
780{
781    def_resp;
782    uint8_t emmreq[0xC0];
783    memset(emmreq,0xCC,0xC0);
784    emmreq[ 7]=0x05;
785    emmreq[ 8]=0x8A;
786    emmreq[ 9]=0x00;
787    emmreq[10]=0x00;
788    emmreq[11]=0x00;
789    emmreq[12]=0x00;
790    emmreq[13]=0x01;
791    memcpy(&emmreq[14],ep->emm + 9, ep->emm[9]+1);
792    do_cas7_cmd(reader,cta_res,&cta_lr,emmreq,sizeof(emmreq),0xB0);
793    if(cta_res[cta_lr-2] != 0x90 && cta_res[cta_lr-1] != 0x00){
794        rdr_log(reader, "(EMM) Reader will be restart now cause: %02X %02X card answer!!!", cta_res[cta_lr-2], cta_res[cta_lr-1]);
795        reader->card_status = CARD_NEED_INIT;
796        add_job(reader->client, ACTION_READER_RESTART, NULL, 0);
797    }
798    return OK;
799}
800
801const struct s_cardsystem reader_nagracak7 =
802{
803    .desc           = "Nagra_Merlin",
804    .caids          = (uint16_t[]){ 0x18, 0x0 },
805    .do_emm         = nagra7_do_emm,
806    .do_ecm         = nagra7_do_ecm,
807    .post_process   = nagra7_post_process,
808    .card_info      = nagra7_card_info,
809    .card_init      = nagra7_card_init,
810    .get_emm_type   = nagra7_get_emm_type,
811    .get_emm_filter = nagra7_get_emm_filter,
812};
813
814#endif
Note: See TracBrowser for help on using the repository browser.