source: trunk/reader-nagra.c @ 5375

Last change on this file since 5375 was 5309, checked in by Admin, 8 years ago

Get rid of some static variables and cl->dump usage as they are not threadsafe.

File size: 35.2 KB
Line 
1#include "globals.h"
2#include "reader-common.h"
3#include "cscrypt/idea.h"
4#include <termios.h>
5#include <unistd.h>
6
7// Card Status checks
8#define HAS_CW()      ((reader->cam_state[2]&6)==6)
9#define RENEW_SESSIONKEY() ((reader->cam_state[0]&128)==128 || (reader->cam_state[0]&64)==64 || (reader->cam_state[0]&32)==32 || (reader->cam_state[2]&8)==8)
10#define SENDDATETIME() (reader->cam_state[0]&8)
11// Datatypes
12#define DT01        0x01
13#define IRDINFO     0x00
14#define TIERS       0x05
15#define DT06        0x06
16#define CAMDATA     0x08
17
18#define MAX_REC     20
19#define SYSTEM_NAGRA 0x1800
20#define SYSTEM_MASK 0xFF00
21
22
23static time_t tier_date(uint32_t date, char *buf, int32_t l)
24{
25  time_t ut=870393600L+date*(24*3600);
26  if (buf)
27  {
28    struct tm *t;
29    t=gmtime(&ut);
30    snprintf(buf, l, "%04d/%02d/%02d", t->tm_year+1900, t->tm_mon+1, t->tm_mday);
31  }
32  return(ut);
33}
34
35static int32_t do_cmd(struct s_reader * reader, unsigned char cmd, int32_t ilen, unsigned char res, int32_t rlen, unsigned char *data, unsigned char * cta_res, uint16_t * p_cta_lr)
36{
37    /*
38    here we build the command related to the protocol T1 for ROM142 or T14 for ROM181
39    the only different that i know is the command length byte msg[4], this msg[4]+=1 by a ROM181 smartcard (_nighti_)
40    one example for the cmd$C0
41    T14 protocol:       01 A0 CA 00 00 03 C0 00 06 91
42    T1  protocol: 21 00 08 A0 CA 00 00 02 C0 00 06 87
43    */
44    int32_t msglen=ilen+6;
45    unsigned char msg[msglen];
46    static const char nagra_head[] = {0xA0, 0xCA, 0x00, 0x00};
47
48    memset(msg, 0, msglen);
49    memcpy(msg,nagra_head,4);
50    msg[4] = ilen;
51    msg[5] = cmd;
52    int32_t dlen=ilen-2;
53    msg[6] = dlen;
54    if(data && dlen>0) memcpy(msg+7,data,dlen);
55    msg[dlen+7] = rlen;
56    if (dlen<0)
57    {
58        cs_debug_mask(D_READER, "[nagra-reader] invalid data length encountered");
59            return ERROR;
60        }
61        if (reader->is_pure_nagra==1)
62        {
63            msg[4]+=1;
64        }
65        if(!reader_cmd2icc(reader, msg,msglen, cta_res, p_cta_lr))
66    {
67        cs_sleepms(5);
68        if(cta_res[0]!=res) 
69            {
70                cs_debug_mask(D_READER, "[nagra-reader] result not expected (%02x != %02x)",cta_res[0],res);
71                return ERROR;
72            }
73            if((*p_cta_lr-2)!=rlen) 
74            {
75                cs_debug_mask(D_READER, "[nagra-reader] result length expected (%d != %d)",(*p_cta_lr-2),rlen);
76                return ERROR;
77            }
78            return *p_cta_lr;
79        }       
80        return ERROR;
81}
82
83static void ReverseMem(unsigned char *vIn, int32_t len)
84{
85    unsigned char temp;
86    int32_t i;
87    for(i=0; i < (len/2); i++)
88    {
89        temp = vIn[i];
90        vIn[i] = vIn[len-i-1];
91        vIn[len-i-1] = temp;
92    }
93}
94
95static void Signature(unsigned char *sig, const unsigned char *vkey,const unsigned char *msg, int32_t len) 
96{
97    IDEA_KEY_SCHEDULE ks;
98    unsigned char v[8];
99    unsigned char b200[16];
100    unsigned char b0f0[8];
101    memcpy(b200,vkey,sizeof(b200));
102    int32_t i;
103    int32_t j;
104    for(i=0; i<len; i+=8)
105    {
106        idea_set_encrypt_key(b200,&ks);
107        memset(v,0,sizeof(v));
108        idea_cbc_encrypt(msg+i,b0f0,8,&ks,v,IDEA_DECRYPT);
109        for(j=7; j>=0; j--) b0f0[j]^=msg[i+j];
110        memcpy(b200+0,b0f0,8);
111        memcpy(b200+8,b0f0,8);
112    }
113    memcpy(sig,b0f0,8);
114    return;
115}
116
117static int32_t CamStateRequest(struct s_reader * reader)
118{
119    def_resp;
120    if(do_cmd(reader, 0xC0,0x02,0xB0,0x06,NULL,cta_res,&cta_lr))
121    {
122        memcpy(reader->cam_state,cta_res+3,3);
123        cs_debug_mask(D_READER, "[nagra-reader] Camstate: %s",cs_hexdump (1, reader->cam_state, 3));
124    }
125    else
126    {
127        cs_debug_mask(D_READER, "[nagra-reader] CamStateRequest failed");
128        return ERROR;
129    }
130    return OK;
131}
132
133static void DateTimeCMD(struct s_reader * reader)
134{
135    def_resp;
136    if (!do_cmd(reader, 0xC8,0x02,0xB8,0x06,NULL,cta_res,&cta_lr))
137    {
138        cs_debug_mask(D_READER, "[nagra-reader] DateTimeCMD failed!");
139    }
140       
141}
142
143static int32_t NegotiateSessionKey_Tiger(struct s_reader * reader)
144{
145    def_resp;
146    unsigned char vFixed[] = {0,1,2,3,0x11};
147    unsigned char parte_fija[120];
148    unsigned char parte_variable[88];
149    unsigned char d1_rsa_modulo[88];
150    unsigned char d2_data[88];
151    unsigned char sign1[8];
152    unsigned char sk[16];
153    unsigned char tmp[104];
154    unsigned char idea_sig[16];
155    unsigned char random[88];
156                     
157    if(!do_cmd(reader, 0xd1,0x02,0x51,0xd2,NULL,cta_res,&cta_lr))
158    {
159        cs_debug_mask(D_READER, "[nagra-reader] CMD$D1 failed");
160        return ERROR;
161    }
162   
163    BN_CTX *ctx = BN_CTX_new();
164#ifdef WITH_LIBCRYPTO
165    BN_CTX_start(ctx);
166#endif
167    BIGNUM *bnN = BN_CTX_get(ctx);
168    BIGNUM *bnE = BN_CTX_get(ctx);
169    BIGNUM *bnCT = BN_CTX_get(ctx);
170    BIGNUM *bnPT = BN_CTX_get(ctx);
171    BN_bin2bn(reader->rsa_mod, 120, bnN);
172    BN_bin2bn(vFixed+4, 1, bnE);
173    BN_bin2bn(&cta_res[90], 120, bnCT);
174    BN_mod_exp(bnPT, bnCT, bnE, bnN, ctx);
175    memset(parte_fija, 0, 120);
176    BN_bn2bin(bnPT, parte_fija + (120-BN_num_bytes(bnPT)));
177    BN_CTX_end(ctx);
178    BN_CTX_free (ctx);
179   
180    cs_debug_mask(D_READER, "[nagra-reader] ---------- SIG CHECK ---------------------");
181    memset(tmp,0, 104);
182    memcpy(tmp+4, parte_fija+11, 100);
183    memset(idea_sig, 0x37, 16);
184    Signature(sign1, idea_sig, tmp, 104);
185    cs_debug_mask(D_READER, "[nagra-reader] sign1: %s", cs_hexdump (0, sign1, 8));
186    cs_debug_mask(D_READER, "[nagra-reader] sign2: %s", cs_hexdump (0, parte_fija+111, 8));
187    if (!memcmp (parte_fija+111, sign1, 8)==0)
188    {
189        cs_debug_mask(D_READER, "[nagra-reader] signature check nok");
190        cs_debug_mask(D_READER, "[nagra-reader] ------------------------------------------");
191        return ERROR;
192    }
193    cs_debug_mask(D_READER, "[nagra-reader] signature check ok");
194    cs_debug_mask(D_READER, "[nagra-reader] ------------------------------------------");
195   
196    memcpy(reader->hexserial+2, parte_fija+15, 4);
197    memcpy(reader->sa[0], parte_fija+15, 2);
198
199    memcpy(reader->irdId, parte_fija+19, 4);
200    memcpy(d1_rsa_modulo,parte_fija+23,88);
201   
202    ReverseMem(cta_res+2, 88);
203    BN_CTX *ctx1 = BN_CTX_new();
204#ifdef WITH_LIBCRYPTO
205    BN_CTX_start(ctx1);
206#endif
207    BIGNUM *bnN1 = BN_CTX_get(ctx1);
208    BIGNUM *bnE1 = BN_CTX_get(ctx1);
209    BIGNUM *bnCT1 = BN_CTX_get(ctx1);
210    BIGNUM *bnPT1 = BN_CTX_get(ctx1);
211    BN_bin2bn(d1_rsa_modulo, 88, bnN1);
212    BN_bin2bn(vFixed+4, 1, bnE1);
213    BN_bin2bn(cta_res+2, 88, bnCT1);
214    BN_mod_exp(bnPT1, bnCT1, bnE1, bnN1, ctx1);
215    memset(parte_variable, 0, 88);
216    BN_bn2bin(bnPT1, parte_variable + (88-BN_num_bytes(bnPT1)));
217    BN_CTX_end(ctx1);
218    BN_CTX_free (ctx1);
219
220    reader->ActivationDate[0] = parte_variable[65];
221    reader->ActivationDate[1] = parte_variable[66];
222    reader->ExpiryDate[0] = parte_variable[69];
223    reader->ExpiryDate[1] = parte_variable[70];
224   
225    reader->prid[0][0]=0x00;
226    reader->prid[0][1]=0x00;
227    reader->prid[0][2]=parte_variable[73];
228    reader->prid[0][3]=parte_variable[74];
229    reader->caid =(SYSTEM_NAGRA|parte_variable[76]);
230    memcpy(sk,&parte_variable[79],8);                                                                           
231    memcpy(sk+8,&parte_variable[79],8); 
232    cs_ri_log(reader, "type: NAGRA, caid: %04X, IRD ID: %s",reader->caid, cs_hexdump (1,reader->irdId,4));
233    cs_ri_log(reader, "ProviderID: %s",cs_hexdump (1,reader->prid[0],4));
234
235    memset(random, 0, 88);
236    memcpy(random, sk,16);
237    ReverseMem(random, 88);
238   
239   
240    BN_CTX *ctx3 = BN_CTX_new();
241#ifdef WITH_LIBCRYPTO
242    BN_CTX_start(ctx3);
243#endif
244    BIGNUM *bnN3 = BN_CTX_get(ctx3);
245    BIGNUM *bnE3 = BN_CTX_get(ctx3);
246    BIGNUM *bnCT3 = BN_CTX_get(ctx3);
247    BIGNUM *bnPT3 = BN_CTX_get(ctx3);
248    BN_bin2bn(d1_rsa_modulo, 88, bnN3);
249    BN_bin2bn(vFixed+4, 1, bnE3);
250    BN_bin2bn(random, 88, bnCT3);
251    BN_mod_exp(bnPT3, bnCT3, bnE3, bnN3, ctx3);
252    memset(d2_data, 0, 88);
253    BN_bn2bin(bnPT3, d2_data + (88-BN_num_bytes(bnPT3)));
254    BN_CTX_end(ctx3);
255    BN_CTX_free (ctx3);
256    ReverseMem(d2_data, 88);
257
258    if(!do_cmd(reader, 0xd2,0x5a,0x52,0x03, d2_data,cta_res,&cta_lr)) 
259    {
260        cs_debug_mask(D_READER, "[nagra-reader] CMD$D2 failed");
261        return ERROR;
262    }
263    if (cta_res[2] == 0x00)
264    {
265        memcpy(reader->sessi,sk,16);
266        IDEA_KEY_SCHEDULE ks;
267        idea_set_encrypt_key(reader->sessi,&ks);
268        idea_set_decrypt_key(&ks,&reader->ksSession);
269        cs_debug_mask(D_READER, "[nagra-reader] Tiger session key negotiated");
270        return OK;
271    }
272    cs_ri_log(reader, "Negotiate sessionkey was not successfull! Please check tivusat rsa key");
273    return ERROR;
274       
275}
276
277static int32_t NegotiateSessionKey(struct s_reader * reader)
278{
279    def_resp;
280    unsigned char negot[64];
281    unsigned char cmd2b[] = {0x21, 0x40, 0x4D, 0xA0, 0xCA, 0x00, 0x00, 0x47, 0x27, 0x45,
282                            0x1C, 0x54, 0xd1, 0x26, 0xe7, 0xe2, 0x40, 0x20,
283                            0xd1, 0x66, 0xf4, 0x18, 0x97, 0x9d, 0x5f, 0x16,
284                            0x8f, 0x7f, 0x7a, 0x55, 0x15, 0x82, 0x31, 0x14,
285                            0x06, 0x57, 0x1a, 0x3f, 0xf0, 0x75, 0x62, 0x41,
286                            0xc2, 0x84, 0xda, 0x4c, 0x2e, 0x84, 0xe9, 0x29,
287                            0x13, 0x81, 0xee, 0xd6, 0xa9, 0xf5, 0xe9, 0xdb,
288                            0xaf, 0x22, 0x51, 0x3d, 0x44, 0xb3, 0x20, 0x83,
289                            0xde, 0xcb, 0x5f, 0x35, 0x2b, 0xb0, 0xce, 0x70,
290                            0x01, 0x02, 0x03, 0x04, //IRD nr
291                            0x00};//keynr
292    unsigned char tmp[64];
293    unsigned char idea1[16];
294    unsigned char idea2[16];
295    unsigned char sign1[8];
296    unsigned char sign2[8];
297
298    if (reader->is_tiger)
299    {
300        if (!NegotiateSessionKey_Tiger(reader))
301        {
302            cs_debug_mask(D_READER, "[nagra-reader] NegotiateSessionKey_Tiger failed");
303            return ERROR;
304        }
305        return OK;
306    }
307
308    if (!reader->has_dt08) // if we have no valid dt08 calc then we use rsa from config and hexserial for calc of sessionkey
309    {
310        memcpy(reader->plainDT08RSA, reader->rsa_mod, 64); 
311        memcpy(reader->signature,reader->nagra_boxkey, 8);
312    }
313   
314    if ((reader->is_n3_na) && (!do_cmd(reader, 0x29,0x02,0xA9,0x04, NULL,cta_res,&cta_lr)))
315        return ERROR;
316   
317    memcpy(tmp, reader->irdId, 4);
318    tmp[4]=0; //keynr 0
319
320    if (!reader->is_n3_na) {
321        if (!do_cmd(reader, 0x2a,0x02,0xaa,0x42,NULL,cta_res,&cta_lr)) {
322            cs_debug_mask(D_READER, "[nagra-reader] CMD$2A failed");
323            return ERROR;
324        }
325    }
326    else
327        if (!do_cmd(reader, 0x26,0x07,0xa6, 0x42, tmp,cta_res,&cta_lr)) {
328            cs_debug_mask(D_READER, "[nagra-reader] CMD$26 failed");
329            return ERROR;
330        }
331
332    // RSA decrypt of cmd$2a data, result is stored in "negot"
333    ReverseMem(cta_res+2, 64);
334    unsigned char vFixed[] = {0,1,2,3};
335    BN_CTX *ctx = BN_CTX_new();
336#ifdef WITH_LIBCRYPTO
337    BN_CTX_start(ctx);
338#endif
339    BIGNUM *bnN = BN_CTX_get(ctx);
340    BIGNUM *bnE = BN_CTX_get(ctx);
341    BIGNUM *bnCT = BN_CTX_get(ctx);
342    BIGNUM *bnPT = BN_CTX_get(ctx);
343    BN_bin2bn(reader->plainDT08RSA, 64, bnN);
344    BN_bin2bn(vFixed+3, 1, bnE);
345    BN_bin2bn(cta_res+2, 64, bnCT);
346    BN_mod_exp(bnPT, bnCT, bnE, bnN, ctx);
347    memset(negot, 0, 64);
348    BN_bn2bin(bnPT, negot + (64-BN_num_bytes(bnPT)));
349       
350    memcpy(tmp, negot, 64);
351    ReverseMem(tmp, 64);
352   
353    // build sessionkey
354    // first halve is IDEA Hashed in chuncs of 8 bytes using the Signature1 from dt08 calc, CamID-Inv.CamID(16 bytes key) the results are the First 8 bytes of the Session key
355    memcpy(idea1, reader->signature, 8); 
356    memcpy(idea1+8, reader->hexserial+2, 4);
357    idea1[12] = ~reader->hexserial[2]; idea1[13] = ~reader->hexserial[3]; idea1[14] = ~reader->hexserial[4]; idea1[15] = ~reader->hexserial[5];
358       
359    Signature(sign1, idea1, tmp, 32);
360    memcpy(idea2,sign1,8); memcpy(idea2+8,sign1,8); 
361    Signature(sign2, idea2, tmp, 32);
362    memcpy(reader->sessi,sign1,8); memcpy(reader->sessi+8,sign2,8);
363       
364    // prepare cmd$2b data
365    BN_bin2bn(negot, 64, bnCT);
366    BN_mod_exp(bnPT, bnCT, bnE, bnN, ctx);
367    memset(cmd2b+10, 0, 64);
368    BN_bn2bin(bnPT, cmd2b+10 + (64-BN_num_bytes(bnPT)));
369    BN_CTX_end(ctx);
370    BN_CTX_free (ctx);
371    ReverseMem(cmd2b+10, 64);
372       
373    IDEA_KEY_SCHEDULE ks;
374    idea_set_encrypt_key(reader->sessi,&ks);
375    idea_set_decrypt_key(&ks,&reader->ksSession);
376
377    memcpy(cmd2b+74, reader->irdId, 4);
378    cmd2b[78] = 0; //keynr
379
380    if (!reader->is_n3_na) {
381        if(!do_cmd(reader, 0x2b,0x42,0xab,0x02, cmd2b+10,cta_res,&cta_lr)) {
382            cs_debug_mask(D_READER, "[nagra-reader] CMD$2B failed");
383            return ERROR;
384        }
385    }
386    else if(!do_cmd(reader, 0x27,0x47,0xa7,0x02,cmd2b+10,cta_res,&cta_lr)) {
387        cs_debug_mask(D_READER, "[nagra-reader] CMD$27 failed");
388        return ERROR;
389    }
390   
391    cs_debug_mask(D_READER, "[nagra-reader] session key negotiated");
392   
393    DateTimeCMD(reader);
394   
395    if (!CamStateRequest(reader))
396    {
397        cs_debug_mask(D_READER, "[nagra-reader] CamStateRequest failed");
398        return ERROR;
399    }
400    if RENEW_SESSIONKEY()
401    {
402        cs_ri_log(reader, "Negotiate sessionkey was not successfull! Please check rsa key and boxkey");
403        return ERROR;
404    }
405
406    return OK;
407}
408
409static void decryptDT08(struct s_reader * reader, unsigned char * cta_res)
410{
411    unsigned char vFixed[] = {0,1,2,3};
412    unsigned char v[72];
413    unsigned char buf[72];
414    unsigned char sign2[8];
415    unsigned char static_dt08[73];
416    unsigned char camid[4];
417    int32_t i, n;
418    BN_CTX *ctx;
419    BIGNUM *bn_mod, *bn_exp, *bn_data, *bn_res;
420   
421    memcpy(static_dt08, &cta_res[12], 73);
422    // decrypt RSA Part of dt08
423    bn_mod = BN_new ();
424    bn_exp = BN_new ();
425    bn_data = BN_new ();
426    bn_res = BN_new ();
427    ctx= BN_CTX_new();
428    if (ctx == NULL) { 
429      cs_debug_mask(D_READER, "[nagra-reader] RSA Error in dt08 decrypt");
430    }
431    ReverseMem(static_dt08+1, 64);
432    BN_bin2bn (reader->rsa_mod, 64, bn_mod); // rsa modulus
433    BN_bin2bn (vFixed+3, 1, bn_exp); // exponent
434    BN_bin2bn (static_dt08+1, 64, bn_data);
435    BN_mod_exp (bn_res, bn_data, bn_exp, bn_mod, ctx);
436    memset (static_dt08+1, 0, 64);
437    n = BN_bn2bin (bn_res, static_dt08+1);
438    BN_CTX_free (ctx);
439    ReverseMem(static_dt08+1, n);
440   
441    // RSA data can never be bigger than the modulo
442    static_dt08[64] |= static_dt08[0] & 0x80;
443   
444    // IdeaCamKey
445    memcpy (&reader->IdeaCamKey[0], reader->nagra_boxkey, 8);
446    memcpy (&reader->IdeaCamKey[8], reader->irdId, 4);
447    for (i = 0; i < 4; i++)
448            reader->IdeaCamKey[12 + i] = ~reader->irdId[i];
449       
450    // now IDEA decrypt
451    IDEA_KEY_SCHEDULE ks;
452    idea_set_encrypt_key(reader->IdeaCamKey,&ks);
453    idea_set_decrypt_key(&ks,&reader->ksSession);
454    memcpy (&buf[0], static_dt08+1, 64);
455    memcpy (&buf[64], static_dt08+65, 8);
456    memset(v,0,sizeof(v));
457    memset(static_dt08,0,sizeof(static_dt08));
458    idea_cbc_encrypt(buf,static_dt08,72,&reader->ksSession,v,IDEA_DECRYPT);
459   
460    if (reader->swapCW==1)
461    {
462        memset(camid,0xff,4);
463    }
464    else
465    {
466        memcpy(camid, reader->hexserial+2,4);
467    }
468    cs_debug_mask(D_READER, "[nagra-reader] using camid %s for dt08 calc",cs_hexdump (1,camid,4));
469   
470    // Calculate reader->signature
471    memcpy (reader->signature, static_dt08, 8);
472    memset (static_dt08 + 0, 0, 4);
473    memcpy (static_dt08 + 4, camid, 4);
474    Signature(sign2,reader->IdeaCamKey,static_dt08,72);
475   
476    if (memcmp (reader->signature, sign2, 8)==0)
477    {
478        reader->has_dt08=1;
479        memcpy (reader->plainDT08RSA, static_dt08+8, 64);
480        cs_debug_mask(D_READER, "[nagra-reader] DT08 signature check ok");
481    }
482    else
483    {
484        reader->has_dt08=0;
485        cs_debug_mask(D_READER, "[nagra-reader] DT08 signature check nok");
486    }   
487   
488    BN_free( bn_mod );
489    BN_free( bn_exp );
490    BN_free( bn_data );
491    BN_free( bn_res );
492}
493
494static void addProvider(struct s_reader * reader, unsigned char * cta_res)
495{
496    int32_t i;
497    int32_t toadd=1;
498    for (i=0; i<reader->nprov; i++)
499    {
500        if ((cta_res[7]==reader->prid[i][2]) && (cta_res[8]==reader->prid[i][3]))
501        {
502            toadd = 0;
503        }
504    }
505    if (toadd)
506    {
507        reader->prid[reader->nprov][0]=0;
508        reader->prid[reader->nprov][1]=0;
509        reader->prid[reader->nprov][2]=cta_res[7];
510        reader->prid[reader->nprov][3]=cta_res[8];
511        memcpy(reader->sa[reader->nprov], reader->sa[0], 4);
512        reader->nprov+=1;
513    }
514}           
515
516static int32_t ParseDataType(struct s_reader * reader, unsigned char dt, unsigned char * cta_res, uint16_t cta_lr)
517{
518    char ds[16], de[16];
519        uint16_t chid;
520    switch(dt) 
521    {
522        case IRDINFO:
523        {
524            reader->prid[0][0]=0;
525            reader->prid[0][1]=0;
526            reader->prid[0][2]=cta_res[7];
527            reader->prid[0][3]=cta_res[8];
528            if ( ((cta_res[7] == 0x34) && (cta_res[8] == 0x11)) || ((cta_res[7] == 0x04) && (cta_res[8] == 0x01))) //provider 3411, 0401 needs cw swap
529            {
530                cs_debug_mask(D_READER, "[nagra-reader] detect provider with swap cw!");
531                reader->swapCW=1;
532            }
533           
534            reader->prid[1][0]=0x00;
535            reader->prid[1][1]=0x00;
536            reader->prid[1][2]=0x00;
537            reader->prid[1][3]=0x00;
538            memcpy(reader->sa[1], reader->sa[0], 4);
539            reader->nprov+=1;
540                   
541            reader->caid =(SYSTEM_NAGRA|cta_res[11]);
542                    memcpy(reader->irdId,cta_res+14,4);
543                    cs_debug_mask(D_READER, "[nagra-reader] type: NAGRA, caid: %04X, IRD ID: %s",reader->caid, cs_hexdump (1,reader->irdId,4));
544                    cs_debug_mask(D_READER, "[nagra-reader] ProviderID: %s",cs_hexdump (1,reader->prid[0],4));
545                    return OK;
546            }
547        case TIERS:
548            if ((cta_lr>33) && (chid=b2i(2, cta_res+11)))
549                {
550                    int32_t id=(cta_res[7]*256)|cta_res[8];
551                    tier_date(b2i(2, cta_res+20)-0x7f7, ds, 15);
552                    tier_date(b2i(2, cta_res+13)-0x7f7, de, 15);
553                    cs_ri_log(reader, "|%04X|%04X    |%s  |%s  |", id,chid, ds, de);
554                    addProvider(reader, cta_res); 
555                }
556            case 0x08:
557            case 0x88: if (cta_res[11] == 0x49) decryptDT08(reader, cta_res);           
558            default:
559                return OK;
560    }
561    return ERROR;
562}
563
564static int32_t GetDataType(struct s_reader * reader, unsigned char dt, int32_t len, int32_t shots)
565{
566    def_resp;
567    int32_t i;
568    for(i=0; i<shots; i++)
569    {
570        if(!do_cmd(reader, 0x22,0x03,0xA2,len,&dt,cta_res,&cta_lr))
571        {
572            cs_debug_mask(D_READER, "[nagra-reader] failed to get datatype %02X",dt);
573            return ERROR;
574        }
575            if((cta_res[2]==0) && (dt != 0x08 || dt != 0x88)) return OK;
576            if(!ParseDataType(reader, dt&0x0F, cta_res, cta_lr)) return ERROR;
577            if ((dt != 0x08 || dt != 0x88) && (cta_res[11] == 0x49)) return OK; //got dt08 data
578            dt|=0x80; // get next item
579        }
580    return OK;
581}
582
583static int32_t nagra2_card_init(struct s_reader * reader, ATR newatr)
584{
585    get_atr;
586    def_resp;
587    memset(reader->rom, 0, 15);
588    reader->is_pure_nagra = 0; 
589    reader->is_tiger = 0; 
590    reader->is_n3_na = 0;
591    reader->has_dt08 = 0; 
592    reader->swapCW = 0; 
593    memset(reader->irdId, 0xff, 4);
594    memset(reader->hexserial, 0, 8); 
595   
596    if(memcmp(atr+11,"DNASP240",8)==0 || memcmp(atr+11,"DNASP241", 8)==0) {
597        cs_ri_log(reader, "detect nagra 3 NA card");
598        memcpy(reader->rom,atr+11,15);
599        reader->is_n3_na=1;
600    }
601    else if (memcmp(atr+11, "DNASP", 5)==0)
602    {
603        cs_ri_log(reader, "detect native nagra card");
604        memcpy(reader->rom,atr+11,15);
605    }
606    else if (memcmp(atr+11, "TIGER", 5)==0 || (memcmp(atr+11, "NCMED", 5)==0))
607    {
608        cs_ri_log(reader, "detect nagra tiger card");
609        memcpy(reader->rom,atr+11,15);
610        reader->is_tiger=1;
611    }
612    else if ((!memcmp(atr+4, "IRDETO", 6)) && ((atr[14]==0x03) && (atr[15]==0x84) && (atr[16]==0x55)))
613    {
614        cs_ri_log(reader, "detect irdeto tunneled nagra card");
615        if(check_filled(reader->rsa_mod, 64) == 0)
616        {
617            cs_ri_log(reader, "no rsa key configured -> using irdeto mode");
618            return ERROR;
619        }
620        if(reader->force_irdeto)
621        {
622            cs_ri_log(reader, "rsa key configured but irdeto mode forced -> using irdeto mode");
623            return ERROR;
624        }
625        cs_ri_log(reader, "rsa key configured -> using nagra mode");
626        reader->is_pure_nagra=1;
627        if(!do_cmd(reader, 0x10,0x02,0x90,0x11,0,cta_res,&cta_lr))
628        {
629            cs_debug_mask(D_READER, "[nagra-reader] get rom version failed");
630            return ERROR;
631        }
632        memcpy(reader->rom,cta_res+2,15);
633    }
634    else return ERROR;
635
636    reader->nprov = 1;
637
638    if (!reader->is_tiger)
639    {
640        CamStateRequest(reader);
641        if(!do_cmd(reader, 0x12,0x02,0x92,0x06,0,cta_res,&cta_lr)) 
642        {
643            cs_debug_mask(D_READER, "[nagra-reader] get serial failed");
644            return ERROR;
645        }
646        memcpy(reader->hexserial+2, cta_res+2, 4);
647        cs_debug_mask(D_READER, "[nagra-reader] SER:  %s", cs_hexdump (1, reader->hexserial+2, 4));
648        memcpy(reader->sa[0], cta_res+2, 2);
649       
650        if(!GetDataType(reader, DT01,0x0E,MAX_REC)) return ERROR;
651        cs_debug_mask(D_READER, "[nagra-reader] DT01 DONE");
652        CamStateRequest(reader);
653        if(!GetDataType(reader, IRDINFO,0x39,MAX_REC)) return ERROR;
654        cs_debug_mask(D_READER, "[nagra-reader] IRDINFO DONE");
655        CamStateRequest(reader);
656        if(!GetDataType(reader, CAMDATA,0x55,10)) return ERROR;
657        cs_debug_mask(D_READER, "[nagra-reader] CAMDATA Done");
658        if(!GetDataType(reader, 0x04,0x44,MAX_REC)) return ERROR;
659        cs_debug_mask(D_READER, "[nagra-reader] DT04 DONE");
660        CamStateRequest(reader);
661       
662        if (!memcmp(reader->rom+5, "181", 3)==0) //dt05 is not supported by rom181
663        {
664            cs_ri_log(reader, "-----------------------------------------");
665            cs_ri_log(reader, "|id  |tier    |valid from  |valid to    |");
666            cs_ri_log(reader, "+----+--------+------------+------------+");
667            if(!GetDataType(reader, TIERS,0x57,MAX_REC)) return ERROR;
668            cs_ri_log(reader, "-----------------------------------------");
669            CamStateRequest(reader);
670        }
671       
672        if(!GetDataType(reader, DT06,0x16,MAX_REC)) return ERROR;
673        cs_debug_mask(D_READER, "[nagra-reader] DT06 DONE");
674        CamStateRequest(reader);
675    }
676    if (!NegotiateSessionKey(reader))
677    {
678        cs_debug_mask(D_READER, "[nagra-reader] NegotiateSessionKey failed");
679        return ERROR;
680    }
681    if ((reader->cardmhz != 368) && (reader->is_pure_nagra==0))
682        cs_log("WARNING: For NAGRA2 cards you will have to set 'cardmhz = 368' in oscam.server");
683   
684    return OK;
685}
686
687static char *tiger_date(uint8_t *ndays, int32_t offset, char *result)
688{
689   struct tm tms;
690   memset(&tms, 0, sizeof(tms));
691   int32_t days = (ndays[0] << 8 | ndays[1]) + offset;
692   int32_t year_offset = 0;
693   if (days > 0x41B4) year_offset = 68; // to overcome 32-bit systems limitations
694   tms.tm_year = 92 - year_offset;
695   tms.tm_mday = days + 1;
696   mktime(&tms);
697   snprintf(result, 11, "%02d/%02d/%04d", tms.tm_mday, tms.tm_mon + 1, tms.tm_year + 1900 + year_offset);
698   return result;
699}
700
701typedef struct
702{
703   char date1[11];
704   char date2[11];
705   uint8_t type;
706   uint16_t value;
707   uint16_t price;
708} ncmed_rec;
709
710static int32_t reccmp(const void *r1, const void *r2)
711{
712   int32_t v1, v2, y, m, d;
713   sscanf(((ncmed_rec *)r1)->date1, "%02d/%02d/%04d", &d, &m, &y);
714   v1 = y * 372 + 1 + m * 31 + d;
715   sscanf(((ncmed_rec *)r2)->date1, "%02d/%02d/%04d", &d, &m, &y);
716   v2 = y * 372 + 1 + m * 31 + d;
717   return (v1 == v2) ? 0 : (v1 < v2) ? -1 : 1;
718}
719
720static int32_t reccmp2(const void *r1, const void *r2)
721{
722   char rec1[13], rec2[13];
723   snprintf(rec1, sizeof(rec1), "%04X", ((ncmed_rec *)r1)->value);
724   memcpy(rec1+4, ((ncmed_rec *)r1)->date2+6, 4);
725   memcpy(rec1+8, ((ncmed_rec *)r1)->date2+3, 2);
726   memcpy(rec1+10, ((ncmed_rec *)r1)->date2, 2);
727   snprintf(rec2, sizeof(rec2), "%04X", ((ncmed_rec *)r2)->value);
728   memcpy(rec2+4, ((ncmed_rec *)r2)->date2+6, 4);
729   memcpy(rec2+8, ((ncmed_rec *)r2)->date2+3, 2);
730   memcpy(rec2+10, ((ncmed_rec *)r2)->date2, 2);
731   rec1[12] = rec2[12] = 0;
732   return strcmp(rec2, rec1);
733}
734
735static int32_t nagra2_card_info(struct s_reader * reader)
736{
737    int32_t i;
738        char currdate[11];
739    cs_ri_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]);
740    cs_ri_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]);
741    cs_ri_log(reader, "SER:    %s", cs_hexdump (1, reader->hexserial+2, 4));
742    cs_ri_log(reader, "CAID:   %04X",reader->caid);
743    cs_ri_log(reader, "Prv.ID: %s(sysid)",cs_hexdump (1,reader->prid[0],4));
744    for (i=1; i<reader->nprov; i++)
745    {
746          cs_ri_log(reader, "Prv.ID: %s",cs_hexdump (1,reader->prid[i],4));
747    }
748        if(reader->is_tiger)
749        {
750      cs_ri_log(reader, "Activation Date : %s", tiger_date(reader->ActivationDate, 0, currdate));
751      cs_ri_log(reader, "Expiry Date : %s", tiger_date(reader->ExpiryDate, 0, currdate));
752        }
753        if (reader->nagra_read && reader->is_tiger && memcmp(reader->rom, "NCMED", 5) == 0)
754        {
755           ncmed_rec records[255];
756           int32_t num_records = 0;
757           uint8_t tier_cmd1[] = { 0x00, 0x00 };
758           uint8_t tier_cmd2[] = { 0x01, 0x00 };
759           def_resp;
760           int32_t j;
761           do_cmd(reader, 0xD0, 0x04, 0x50, 0x0A, tier_cmd1, cta_res, &cta_lr);
762           if (cta_lr == 0x0C)
763           {
764              int32_t prepaid = 0;
765              int32_t credit = 0;
766              int32_t balance = 0;
767
768              uint16_t credit_in = cta_res[8] << 8 | cta_res[9];
769              uint16_t credit_out = cta_res[5] << 8 | cta_res[6]; 
770              balance = (credit_in - credit_out) / 100;
771
772              for (i = 0; i < 13; ++i)
773              {
774                 tier_cmd2[1] = i;
775                 do_cmd(reader, 0xD0, 0x04, 0x50, 0xAA, tier_cmd2, cta_res, &cta_lr);
776                 if (cta_lr == 0xAC)
777                 {
778                    //cs_dump(cta_res, cta_lr, "NCMED Card Record #%d", i+1);
779                    for (j = 2; j < cta_res[1] - 14; ++j)
780                    {
781                       if (cta_res[j] == 0x80 && cta_res[j+6] != 0x00)
782                       {
783                          int32_t val_offs = 0;
784                          tiger_date(&cta_res[j+6], 0, records[num_records].date2);
785
786                          switch (cta_res[j+1])
787                          {
788                             case 0x00:
789                             case 0x01:
790                             case 0x20:
791                             case 0x21:
792                             case 0x29:
793                                tiger_date(&cta_res[j+8], 0, records[num_records].date1);
794                                val_offs = 1;
795                                break;
796
797                             case 0x80:
798                                tiger_date(&cta_res[j+6], 0, records[num_records].date1);
799                                val_offs = 1;
800                                break;
801
802                             default:
803                                cs_ri_log(reader, "Unknown record : %s", cs_hexdump(1, &cta_res[j], 17));
804                          }
805                          if (val_offs > 0)
806                          {
807                             records[num_records].type = cta_res[j+1];
808                             records[num_records].value = cta_res[j+4] << 8 | cta_res[j+5];
809                             records[num_records++].price = cta_res[j+11] << 8 | cta_res[j+12];
810                          }
811                          j += 16;
812                       }
813                    }
814                 }
815              }
816              if (reader->nagra_read == 1)
817                 qsort(records, num_records, sizeof(ncmed_rec), reccmp);
818              else
819                 qsort(records, num_records, sizeof(ncmed_rec), reccmp2);
820
821              int32_t  euro=0;
822              char tiername[83];
823              time_t rawtime;
824              struct tm timeinfo;
825              time ( &rawtime );
826              localtime_r(&rawtime, &timeinfo);
827              snprintf(currdate, sizeof(currdate), "%02d/%02d/%04d", timeinfo.tm_mday, timeinfo.tm_mon+1, timeinfo.tm_year+1900);
828             
829              for (i = 0; i < num_records; ++i)
830              { 
831                 switch (records[i].type)
832                 {
833                    case 0x00:
834                    case 0x01: 
835                       if( (reader->nagra_read == 2) && (reccmp(records[i].date2,currdate) >= 0) )
836                         cs_ri_log(reader, "Tier : %04X, expiry date: %s %s",
837                                   records[i].value, records[i].date2, get_tiername(records[i].value, reader->caid, tiername));
838                       else if(reader->nagra_read == 1)
839                       {
840                         euro = (records[i].price / 100);
841                         cs_ri_log(reader, "Activation     : ( %04X ) from %s to %s  (%3d euro) %s",
842                                   records[i].value, records[i].date1, records[i].date2, euro, get_tiername(records[i].value, reader->caid, tiername));
843                       }
844                       break;
845                 
846                    case 0x20:
847                    case 0x21:
848                       if( (reader->nagra_read == 2) && (reccmp(records[i].date2,currdate) >= 0) )
849                       {                         
850                         cs_ri_log(reader, "Tier : %04X, expiry date: %s %s",
851                                   records[i].value, records[i].date2, get_tiername(records[i].value, reader->caid, tiername));
852                       }
853                       break;
854                 }
855                 if (reader->nagra_read == 2)
856                 {
857                    while (i < num_records - 1 && records[i].value == records[i+1].value)
858                       ++i;
859                 }
860              } 
861
862              for (i = 0; i < num_records; ++i)
863              {
864                 switch (records[i].type)
865                 { 
866                    case 0x80:
867                       if(reader->nagra_read == 1)
868                       {
869                         euro = (records[i].price / 100) - prepaid;
870                         credit += euro;
871                         prepaid += euro;
872                         if(euro)
873                           cs_ri_log(reader, "Recharge       :               %s                (%3d euro)",
874                                     records[i].date2, euro);
875                       }
876                       break;
877
878                    case 0x20:
879                    case 0x21:
880                       if(reader->nagra_read == 1)
881                       {
882                         euro = records[i].price / 100;
883                         credit -= euro;
884                         cs_ri_log(reader, "Subscription   : ( %04X ) from %s to %s  (%3d euro) %s",
885                                   records[i].value, records[i].date1, records[i].date2, euro, get_tiername(records[i].value, reader->caid, tiername));
886                       }
887                       break;
888
889                    case 0x29:
890                       euro = records[i].price / 100;
891                       if(reader->nagra_read == 1) credit -= euro;
892                       cs_ri_log(reader, "Event purchase : ( %04X ) from %s to %s  (%3d euro)",
893                                 records[i].value, records[i].date1, records[i].date2, euro);
894                       break;
895                 }
896              }
897              if(reader->nagra_read == 1)
898                cs_ri_log(reader, "Credit         :                                          %3d euro", credit);
899              else
900                cs_ri_log(reader, "Credit : %3d euro", balance);
901           }
902        }
903    cs_log("[nagra-reader] ready for requests"); 
904    return OK;
905}
906
907void nagra2_post_process(struct s_reader * reader)
908{
909    if (!reader->is_tiger)
910    {
911        CamStateRequest(reader);
912        if RENEW_SESSIONKEY() NegotiateSessionKey(reader);
913        if SENDDATETIME() DateTimeCMD(reader);
914    }
915}
916
917static int32_t nagra2_do_ecm(struct s_reader * reader, ECM_REQUEST *er)
918{
919    def_resp;
920    if (!reader->is_tiger)
921    {
922        int32_t retry=0;
923        if (reader->is_n3_na) {
924            unsigned char ecm_pkt[256+16];
925            memset(ecm_pkt, 0, sizeof(ecm_pkt));
926            memcpy(ecm_pkt, er->ecm+3+2, er->ecm[4]);
927           
928            while (!do_cmd(reader, er->ecm[3]+1,er->ecm[4]+5+2,0x88,0x04, ecm_pkt,cta_res,&cta_lr)) {
929                if (retry == 0)
930                    cs_debug_mask(D_READER, "[nagra-reader] nagra2_do_ecm (N3_NA) failed, retry");
931                else {
932                    cs_debug_mask(D_READER, "[nagra-reader] nagra2_do_ecm (N3_NA) failed, retry failed!");
933                    return ERROR;
934                }
935                retry++;
936                cs_sleepms(10);
937            }
938        }
939        else {
940            while (!do_cmd(reader, er->ecm[3],er->ecm[4]+2,0x87,0x02, er->ecm+3+2,cta_res,&cta_lr))
941            {
942                if (retry == 0)
943                    cs_debug_mask(D_READER, "[nagra-reader] nagra2_do_ecm failed, retry");
944                else {
945                    cs_debug_mask(D_READER, "[nagra-reader] nagra2_do_ecm failed, retry failed!");
946                    return ERROR;
947                }
948                retry++;
949                cs_sleepms(10);
950            }
951        }
952        cs_sleepms(10);
953
954        retry=0;
955        while(!CamStateRequest(reader) && retry < 3)
956        {
957            cs_debug_mask(D_READER, "[nagra-reader] CamStateRequest failed, try: %d", retry);
958            retry++;
959                    cs_sleepms(10);
960        }
961        if (HAS_CW() && (do_cmd(reader, 0x1C,0x02,0x9C,0x36,NULL,cta_res,&cta_lr)))
962        {
963            unsigned char v[8];
964            memset(v,0,sizeof(v));
965            idea_cbc_encrypt(&cta_res[30],er->cw,8,&reader->ksSession,v,IDEA_DECRYPT);
966            memset(v,0,sizeof(v));
967            idea_cbc_encrypt(&cta_res[4],er->cw+8,8,&reader->ksSession,v,IDEA_DECRYPT);
968            if (reader->swapCW==1)
969            {
970                cs_debug_mask(D_READER, "[nagra-reader] swap cws");
971                    unsigned char tt[8];
972                    memcpy(&tt[0],&er->cw[0],8);
973                    memcpy(&er->cw[0],&er->cw[8],8);
974                memcpy(&er->cw[8],&tt[0],8);
975                }
976            return OK;
977        }
978    }
979    else
980    {
981        //check ECM prov id
982        if (memcmp(&reader->prid[0][2], er->ecm+5, 2))
983            return ERROR;
984   
985        //                  ecm_data: 80 30 89 D3 87 54 11 10 DA A6 0F 4B 92 05 34 00 ...
986        //serial_data: A0 CA 00 00 8C D3 8A 00 00 00 00 00 10 DA A6 0F .
987        unsigned char ecm_trim[150];
988        memset(ecm_trim, 0, 150);
989        memcpy(&ecm_trim[5], er->ecm+3+2+2, er->ecm[4]+2);
990        if(do_cmd(reader, er->ecm[3],er->ecm[4]+5,0x53,0x16, ecm_trim,cta_res,&cta_lr)) 
991        {
992            if(cta_res[2] == 0x01)
993            {
994
995                unsigned char v[8];
996                memset(v,0,sizeof(v));
997                idea_cbc_encrypt(&cta_res[14],er->cw,8,&reader->ksSession,v,IDEA_DECRYPT);
998                memset(v,0,sizeof(v));
999                idea_cbc_encrypt(&cta_res[6],er->cw+8,8,&reader->ksSession,v,IDEA_DECRYPT);
1000                return OK;
1001            }
1002            cs_debug_mask(D_READER, "[nagra-reader] can't decode ecm");
1003            return ERROR;
1004        }
1005    }
1006    return ERROR;
1007}
1008
1009int32_t nagra2_get_emm_type(EMM_PACKET *ep, struct s_reader * rdr) //returns TRUE if shared emm matches SA, unique emm matches serial, or global or unknown
1010{
1011    switch (ep->emm[0]) {
1012        case 0x83:
1013            memset(ep->hexserial,0,8);
1014            ep->hexserial[0] = ep->emm[5];
1015            ep->hexserial[1] = ep->emm[4];
1016            ep->hexserial[2] = ep->emm[3];
1017            if (ep->emm[7] == 0x10) {
1018                ep->type = SHARED;
1019                return (!memcmp (rdr->hexserial+2, ep->hexserial, 3));
1020            }
1021            else {
1022                ep->hexserial[3] = ep->emm[6];
1023                ep->type = UNIQUE;
1024                return (!memcmp (rdr->hexserial+2, ep->hexserial, 4));
1025            }
1026        case 0x82:
1027            ep->type = GLOBAL;
1028            return TRUE;
1029        default:
1030            ep->type = UNKNOWN;
1031            return TRUE;
1032    }
1033}
1034
1035static void nagra2_get_emm_filter(struct s_reader * rdr, uchar *filter)
1036{
1037    int32_t idx = 2;
1038
1039    filter[0]=0xFF;
1040    filter[1]=0;
1041   
1042    filter[idx++]=EMM_GLOBAL;
1043    filter[idx++]=0;
1044    filter[idx+0]    = 0x82;
1045    filter[idx+0+16] = 0xFF;
1046    filter[1]++;
1047    idx += 32;
1048   
1049    filter[idx++]=EMM_SHARED;
1050    filter[idx++]=0;
1051    filter[idx+0]    = 0x83;
1052    filter[idx+1]    = rdr->hexserial[4];
1053    filter[idx+2]    = rdr->hexserial[3];
1054    filter[idx+3]    = rdr->hexserial[2];
1055    filter[idx+4]    = 0x00;
1056    filter[idx+5]    = 0x10;
1057    memset(filter+idx+0+16, 0xFF, 6);
1058    filter[1]++;
1059    idx += 32;
1060
1061    filter[idx++]=EMM_UNIQUE;
1062    filter[idx++]=0;
1063    filter[idx+0]    = 0x83;
1064    filter[idx+1]    = rdr->hexserial[4];
1065    filter[idx+2]    = rdr->hexserial[3];
1066    filter[idx+3]    = rdr->hexserial[2];
1067    filter[idx+4]    = rdr->hexserial[5];
1068    filter[idx+5]    = 0x00;
1069    memset(filter+idx+0+16, 0xFF, 6);
1070    filter[1]++;
1071    idx += 32;
1072   
1073    return;
1074}
1075
1076static int32_t nagra2_do_emm(struct s_reader * reader, EMM_PACKET *ep)
1077{
1078    def_resp;
1079    if (!reader->is_tiger)
1080    {
1081        if(!do_cmd(reader, ep->emm[8],ep->emm[9]+2,0x84,0x02,ep->emm+8+2,cta_res,&cta_lr))
1082        {
1083            cs_debug_mask(D_READER, "[nagra-reader] nagra2_do_emm failed");
1084            return ERROR;
1085        }
1086        // for slow t14 nagra cards, we must do additional timeout
1087        if (reader->is_pure_nagra==1) 
1088        {
1089            cs_sleepms(300);
1090        }
1091        cs_sleepms(250);
1092        nagra2_post_process(reader);
1093    }
1094    else
1095    {
1096        //check EMM prov id
1097        if (memcmp(&reader->prid[0][2], ep->emm+10, 2))
1098            return ERROR;
1099   
1100        //   emm_data: 82 70 8E 00 00 00 00 00 D3 87 8D 11 C0 F4 B1 27 2C 3D 25 94 ...
1101        //serial_data: A0 CA 00 00 8C D3 8A 01 00 00 00 00 C0 F4 B1 27 2C 3D 25 94 ...
1102        unsigned char emm_trim[150] = { 0x01, 0x00, 0x00, 0x00, 0x00 };
1103        memcpy(&emm_trim[5], ep->emm+3+5+2+2, ep->emm[9]+2);
1104        if(!do_cmd(reader, ep->emm[8],ep->emm[9]+5,0x53,0x16, emm_trim,cta_res,&cta_lr))
1105        {
1106            cs_debug_mask(D_READER, "[nagra-reader] nagra2_do_emm failed");
1107            return ERROR;
1108        }
1109        cs_sleepms(300); 
1110    }
1111    return OK;
1112}
1113
1114void reader_nagra(struct s_cardsystem *ph) 
1115{
1116    ph->do_emm=nagra2_do_emm;
1117    ph->do_ecm=nagra2_do_ecm;
1118    ph->post_process=nagra2_post_process;
1119    ph->card_info=nagra2_card_info;
1120    ph->card_init=nagra2_card_init;
1121    ph->get_emm_type=nagra2_get_emm_type;
1122    ph->get_emm_filter=nagra2_get_emm_filter;
1123    ph->caids[0]=0x18;
1124    ph->desc="nagra";
1125}
Note: See TracBrowser for help on using the repository browser.