source: trunk/reader-nagra.c @ 1766

Last change on this file since 1766 was 1766, checked in by landlord, 10 years ago

New EMM processing, so they can be filtered for DVB API, thanks to dingo35.

File size: 21.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
7IDEA_KEY_SCHEDULE ksSession;
8extern uchar cta_res[];
9extern ushort cta_lr;
10int is_pure_nagra=0;
11int is_tiger=0;
12int has_dt08=0;
13int swapCW=0;
14unsigned char rom[15];
15unsigned char plainDT08RSA[64];
16unsigned char IdeaCamKey[16];
17unsigned char irdId[] = {0xff,0xff,0xff,0xff};
18unsigned char sessi[16];
19unsigned char signature[8];
20unsigned char cam_state[3];
21
22// Card Status checks
23#define HAS_CW()      ((cam_state[2]&6)==6)
24#define RENEW_SESSIONKEY() ((cam_state[0]&128)==128 || (cam_state[0]&64)==64 ||  (cam_state[0]&32)==32 || (cam_state[2]&8)==8)
25#define SENDDATETIME() (cam_state[0]&8)
26// Datatypes
27#define DT01        0x01
28#define IRDINFO     0x00
29#define TIERS       0x05
30#define DT06        0x06
31#define CAMDATA     0x08
32
33#define MAX_REC     20
34#define SYSTEM_NAGRA 0x1800
35#define SYSTEM_MASK 0xFF00
36
37
38static time_t tier_date(ulong date, char *buf, int l)
39{
40  time_t ut=870393600L+date*(24*3600);
41  if (buf)
42  {
43    struct tm *t;
44    t=gmtime(&ut);
45    snprintf(buf, l, "%04d/%02d/%02d", t->tm_year+1900, t->tm_mon+1, t->tm_mday);
46  }
47  return(ut);
48}
49
50static int do_cmd(unsigned char cmd, int ilen, unsigned char res, int rlen, unsigned char *data)
51{
52    /*
53    here we build the command related to the protocol T1 for ROM142 or T14 for ROM181
54    the only different that i know is the command length byte msg[4], this msg[4]+=1 by a ROM181 smartcard (_nighti_)
55    one example for the cmd$C0
56    T14 protocol:       01 A0 CA 00 00 03 C0 00 06 91
57    T1  protocol: 21 00 08 A0 CA 00 00 02 C0 00 06 87
58    */
59    int msglen=ilen+6;
60    unsigned char msg[msglen];
61    static char nagra_head[] = {0xA0, 0xCA, 0x00, 0x00};
62
63    memset(msg, 0, msglen);
64    memcpy(msg,nagra_head,4);
65    msg[4] = ilen;
66    msg[5] = cmd;
67    int dlen=ilen-2;
68    msg[6] = dlen;
69    if(data && dlen>0) memcpy(msg+7,data,dlen);
70    msg[dlen+7] = rlen;
71    if (dlen<0)
72    {
73        cs_debug("[nagra-reader] invalid data length encountered");
74            return ERROR;
75        }
76        if (is_pure_nagra==1)
77        {
78            msg[4]+=1;
79        }
80        if(!reader_cmd2icc(msg,msglen))
81    {
82        cs_sleepms(5);
83        if(cta_res[0]!=res) 
84            {
85                cs_debug("[nagra-reader] result not expected (%02x != %02x)",cta_res[0],res);
86                return ERROR;
87            }
88            if((cta_lr-2)!=rlen) 
89            {
90                cs_debug("[nagra-reader] result length expected (%d != %d)",(cta_lr-2),rlen);
91                return ERROR;
92            }
93            return cta_lr;
94        }       
95        return ERROR;
96}
97
98static void ReverseMem(unsigned char *vIn, int len)
99{
100    unsigned char temp;
101    int i;
102    for(i=0; i < (len/2); i++)
103    {
104        temp = vIn[i];
105        vIn[i] = vIn[len-i-1];
106        vIn[len-i-1] = temp;
107    }
108}
109
110static void Signature(unsigned char *sig, const unsigned char *vkey,const unsigned char *msg, int len) 
111{
112    IDEA_KEY_SCHEDULE ks;
113    unsigned char v[8];
114    unsigned char b200[16];
115    unsigned char b0f0[8];
116    memcpy(b200,vkey,sizeof(b200));
117    int i;
118    int j;
119    for(i=0; i<len; i+=8)
120    {
121        idea_set_encrypt_key(b200,&ks);
122        memset(v,0,sizeof(v));
123        idea_cbc_encrypt(msg+i,b0f0,8,&ks,v,IDEA_DECRYPT);
124        for(j=7; j>=0; j--) b0f0[j]^=msg[i+j];
125        memcpy(b200+0,b0f0,8);
126        memcpy(b200+8,b0f0,8);
127    }
128    memcpy(sig,b0f0,8);
129    return;
130}
131
132static int CamStateRequest(void)
133{
134    if(do_cmd(0xC0,0x02,0xB0,0x06,NULL))
135    {
136        memcpy(cam_state,cta_res+3,3);
137        cs_debug("[nagra-reader] Camstate: %s",cs_hexdump (1, cam_state, 3));
138    }
139    else
140    {
141        cs_debug("[nagra-reader] CamStateRequest failed");
142        return ERROR;
143    }
144    return OK;
145}
146
147static void DateTimeCMD(void)
148{
149    if (!do_cmd(0xC8,0x02,0xB8,0x06,NULL))
150    {
151        cs_debug("[nagra-reader] DateTimeCMD failed!");
152    }
153       
154}
155
156static int NegotiateSessionKey_Tiger(void)
157{
158
159    unsigned char vFixed[] = {0,1,2,3,0x11};
160    unsigned char parte_fija[120];
161    unsigned char parte_variable[88];
162    unsigned char d1_rsa_modulo[88];
163    unsigned char d2_data[88];
164    unsigned char sign1[8];
165    unsigned char sk[16];
166    unsigned char tmp[104];
167    unsigned char idea_sig[16];
168    unsigned char random[88];
169                     
170    if(!do_cmd(0xd1,0x02,0x51,0xd2,NULL))
171    {
172        cs_debug("[nagra-reader] CMD$D1 failed");
173        return ERROR;
174    }
175   
176    BN_CTX *ctx = BN_CTX_new();
177    BIGNUM *bnN = BN_CTX_get(ctx);
178    BIGNUM *bnE = BN_CTX_get(ctx);
179    BIGNUM *bnCT = BN_CTX_get(ctx);
180    BIGNUM *bnPT = BN_CTX_get(ctx);
181    BN_bin2bn(reader[ridx].rsa_mod, 120, bnN);
182    BN_bin2bn(vFixed+4, 1, bnE);
183    BN_bin2bn(&cta_res[90], 120, bnCT);
184    BN_mod_exp(bnPT, bnCT, bnE, bnN, ctx);
185    memset(parte_fija, 0, 120);
186    BN_bn2bin(bnPT, parte_fija + (120-BN_num_bytes(bnPT)));
187    BN_CTX_end(ctx);
188    BN_CTX_free (ctx);
189   
190    cs_debug("[nagra-reader] ---------- SIG CHECK ---------------------");
191    memset(tmp,0, 104);
192    memcpy(tmp+4, parte_fija+11, 100);
193    memset(idea_sig, 0x37, 16);
194    Signature(sign1, idea_sig, tmp, 104);
195    cs_debug("[nagra-reader] sign1: %s", cs_hexdump (0, sign1, 8));
196    cs_debug("[nagra-reader] sign2: %s", cs_hexdump (0, parte_fija+111, 8));
197    if (!memcmp (parte_fija+111, sign1, 8)==0)
198    {
199        cs_debug("[nagra-reader] signature check nok");
200        cs_debug("[nagra-reader] ------------------------------------------");
201        return ERROR;
202    }
203    cs_debug("[nagra-reader] signature check ok");
204    cs_debug("[nagra-reader] ------------------------------------------");
205   
206    memcpy(reader[ridx].hexserial+2, parte_fija+15, 4);
207    memcpy(irdId, parte_fija+19, 4);
208    memcpy(d1_rsa_modulo,parte_fija+23,88);
209   
210    ReverseMem(cta_res+2, 88);
211    BN_CTX *ctx1 = BN_CTX_new();
212    BIGNUM *bnN1 = BN_CTX_get(ctx1);
213    BIGNUM *bnE1 = BN_CTX_get(ctx1);
214    BIGNUM *bnCT1 = BN_CTX_get(ctx1);
215    BIGNUM *bnPT1 = BN_CTX_get(ctx1);
216    BN_bin2bn(d1_rsa_modulo, 88, bnN1);
217    BN_bin2bn(vFixed+4, 1, bnE1);
218    BN_bin2bn(cta_res+2, 88, bnCT1);
219    BN_mod_exp(bnPT1, bnCT1, bnE1, bnN1, ctx1);
220    memset(parte_variable, 0, 88);
221    BN_bn2bin(bnPT1, parte_variable + (88-BN_num_bytes(bnPT1)));
222    BN_CTX_end(ctx1);
223    BN_CTX_free (ctx1);
224   
225    reader[ridx].prid[0][0]=0x00;
226    reader[ridx].prid[0][1]=0x00;
227    reader[ridx].prid[0][2]=parte_variable[73];
228    reader[ridx].prid[0][3]=parte_variable[74];
229    reader[ridx].caid[0] =(SYSTEM_NAGRA|parte_variable[76]);
230    memcpy(sk,&parte_variable[79],8);                                                                           
231    memcpy(sk+8,&parte_variable[79],8); 
232    cs_ri_log("type: NAGRA, caid: %04X, IRD ID: %s",reader[ridx].caid[0], cs_hexdump (1,irdId,4));
233    cs_ri_log("ProviderID: %s",cs_hexdump (1,reader[ridx].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    BIGNUM *bnN3 = BN_CTX_get(ctx3);
242    BIGNUM *bnE3 = BN_CTX_get(ctx3);
243    BIGNUM *bnCT3 = BN_CTX_get(ctx3);
244    BIGNUM *bnPT3 = BN_CTX_get(ctx3);
245    BN_bin2bn(d1_rsa_modulo, 88, bnN3);
246    BN_bin2bn(vFixed+4, 1, bnE3);
247    BN_bin2bn(random, 88, bnCT3);
248    BN_mod_exp(bnPT3, bnCT3, bnE3, bnN3, ctx3);
249    memset(d2_data, 0, 88);
250    BN_bn2bin(bnPT3, d2_data + (88-BN_num_bytes(bnPT3)));
251    BN_CTX_end(ctx3);
252    BN_CTX_free (ctx3);
253    ReverseMem(d2_data, 88);
254
255    if(!do_cmd(0xd2,0x5a,0x52,0x03, d2_data)) 
256    {
257        cs_debug("[nagra-reader] CMD$D2 failed");
258        return ERROR;
259    }
260    if (cta_res[2] == 0x00)
261    {
262        memcpy(sessi,sk,16);
263        IDEA_KEY_SCHEDULE ks;
264        idea_set_encrypt_key(sessi,&ks);
265        idea_set_decrypt_key(&ks,&ksSession);
266        cs_debug("[nagra-reader] session key negotiated");
267        return OK;
268    }
269    cs_ri_log("Negotiate sessionkey was not successfull! Please check tivusat rsa key");
270    return ERROR;
271       
272}
273
274static int NegotiateSessionKey(void)
275{
276    unsigned char cmd2b[] = {0x21, 0x40, 0x48, 0xA0, 0xCA, 0x00, 0x00, 0x43, 0x2B, 0x40, 0x1C, 0x54, 0xd1, 0x26, 0xe7, 0xe2, 0x40, 0x20, 0xd1, 0x66, 0xf4, 0x18, 0x97, 0x9d, 0x5f, 0x16, 0x8f, 0x7f, 0x7a, 0x55, 0x15, 0x82, 0x31, 0x14, 0x06, 0x57, 0x1a, 0x3f, 0xf0, 0x75, 0x62, 0x41, 0xc2, 0x84, 0xda, 0x4c, 0x2e, 0x84, 0xe9, 0x29, 0x13, 0x81, 0xee, 0xd6, 0xa9, 0xf5, 0xe9, 0xdb, 0xaf, 0x22, 0x51, 0x3d, 0x44, 0xb3, 0x20, 0x83, 0xde, 0xcb, 0x5f, 0x35, 0x2b, 0xb0, 0xce, 0x70, 0x02, 0x00};
277    unsigned char negot[64];
278    unsigned char tmp[64];
279    unsigned char idea1[16];
280    unsigned char idea2[16];
281    unsigned char sign1[8];
282    unsigned char sign2[8];
283   
284    if (is_tiger)
285    {
286        if (!NegotiateSessionKey_Tiger())
287        {
288            cs_debug("[nagra-reader] NegotiateSessionKey_Tiger failed");
289            return ERROR;
290        }
291        return OK;
292    }
293    if (!has_dt08) // if we have no valid dt08 calc then we use rsa from config and hexserial for calc of sessionkey
294    {
295        memcpy(plainDT08RSA, reader[ridx].rsa_mod, 64); 
296        memcpy(signature,reader[ridx].nagra_boxkey, 8);
297    }
298    if(!do_cmd(0x2a,0x02,0xaa,0x42,NULL))
299    {
300        cs_debug("[nagra-reader] CMD$2A failed");
301        return ERROR;
302    }
303
304    // RSA decrypt of cmd$2a data, result is stored in "negot"
305    ReverseMem(cta_res+2, 64);
306    unsigned char vFixed[] = {0,1,2,3};
307    BN_CTX *ctx = BN_CTX_new();
308    BIGNUM *bnN = BN_CTX_get(ctx);
309    BIGNUM *bnE = BN_CTX_get(ctx);
310    BIGNUM *bnCT = BN_CTX_get(ctx);
311    BIGNUM *bnPT = BN_CTX_get(ctx);
312    BN_bin2bn(plainDT08RSA, 64, bnN);
313    BN_bin2bn(vFixed+3, 1, bnE);
314    BN_bin2bn(cta_res+2, 64, bnCT);
315    BN_mod_exp(bnPT, bnCT, bnE, bnN, ctx);
316    memset(negot, 0, 64);
317    BN_bn2bin(bnPT, negot + (64-BN_num_bytes(bnPT)));
318       
319    memcpy(tmp, negot, 64);
320    ReverseMem(tmp, 64);
321   
322    // build sessionkey
323    // 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
324    memcpy(idea1, signature, 8); 
325    memcpy(idea1+8, reader[ridx].hexserial+2, 4);
326    idea1[12] = ~reader[ridx].hexserial[2]; idea1[13] = ~reader[ridx].hexserial[3]; idea1[14] = ~reader[ridx].hexserial[4]; idea1[15] = ~reader[ridx].hexserial[5];
327       
328    Signature(sign1, idea1, tmp, 32);
329    memcpy(idea2,sign1,8); memcpy(idea2+8,sign1,8); 
330    Signature(sign2, idea2, tmp, 32);
331    memcpy(sessi,sign1,8); memcpy(sessi+8,sign2,8);
332       
333    // prepare cmd$2b data
334    BN_bin2bn(negot, 64, bnCT);
335    BN_mod_exp(bnPT, bnCT, bnE, bnN, ctx);
336    memset(cmd2b+10, 0, 64);
337    BN_bn2bin(bnPT, cmd2b+10 + (64-BN_num_bytes(bnPT)));
338    BN_CTX_end(ctx);
339    BN_CTX_free (ctx);
340    ReverseMem(cmd2b+10, 64);
341       
342    IDEA_KEY_SCHEDULE ks;
343    idea_set_encrypt_key(sessi,&ks);
344    idea_set_decrypt_key(&ks,&ksSession);
345   
346    if(!do_cmd(0x2b,0x42,0xab,0x02, cmd2b+10))
347    {
348        cs_debug("[nagra-reader] CMD$2B failed");
349        return ERROR;
350    }
351
352    cs_debug("[nagra-reader] session key negotiated");
353   
354    DateTimeCMD();
355   
356    if (!CamStateRequest())
357    {
358        cs_debug("[nagra-reader] CamStateRequest failed");
359        return ERROR;
360    }
361    if RENEW_SESSIONKEY()
362    {
363        cs_ri_log("Negotiate sessionkey was not successfull! Please check rsa key and boxkey");
364        return ERROR;
365    }
366
367    return OK;
368}
369
370static void decryptDT08(void)
371{
372
373    unsigned char vFixed[] = {0,1,2,3};
374    unsigned char v[72];
375    unsigned char buf[72];
376    unsigned char sign2[8];
377    unsigned char static_dt08[73];
378    unsigned char camid[4];
379    int i, n;
380    BN_CTX *ctx;
381    BIGNUM *bn_mod, *bn_exp, *bn_data, *bn_res;
382   
383    memcpy(static_dt08, &cta_res[12], 73);
384    // decrypt RSA Part of dt08
385    bn_mod = BN_new ();
386    bn_exp = BN_new ();
387    bn_data = BN_new ();
388    bn_res = BN_new ();
389    ctx= BN_CTX_new();
390    if (ctx == NULL) cs_debug("[nagra-reader] RSA Error in dt08 decrypt");
391    ReverseMem(static_dt08+1, 64);
392    BN_bin2bn (reader[ridx].rsa_mod, 64, bn_mod); // rsa modulus
393    BN_bin2bn (vFixed+3, 1, bn_exp); // exponent
394    BN_bin2bn (static_dt08+1, 64, bn_data);
395    BN_mod_exp (bn_res, bn_data, bn_exp, bn_mod, ctx);
396    memset (static_dt08+1, 0, 64);
397    n = BN_bn2bin (bn_res, static_dt08+1);
398    BN_CTX_free (ctx);
399    ReverseMem(static_dt08+1, n);
400   
401    // RSA data can never be bigger than the modulo
402    static_dt08[64] |= static_dt08[0] & 0x80;
403   
404    // IdeaCamKey
405    memcpy (&IdeaCamKey[0], reader[ridx].nagra_boxkey, 8);
406    memcpy (&IdeaCamKey[8], irdId, 4);
407    for (i = 0; i < 4; i++)
408            IdeaCamKey[12 + i] = ~irdId[i];
409       
410    // now IDEA decrypt
411    IDEA_KEY_SCHEDULE ks;
412    idea_set_encrypt_key(IdeaCamKey,&ks);
413    idea_set_decrypt_key(&ks,&ksSession);
414    memcpy (&buf[0], static_dt08+1, 64);
415    memcpy (&buf[64], static_dt08+65, 8);
416    memset(v,0,sizeof(v));
417    memset(static_dt08,0,sizeof(static_dt08));
418    idea_cbc_encrypt(buf,static_dt08,72,&ksSession,v,IDEA_DECRYPT);
419   
420    if (swapCW==1)
421    {
422        memset(camid,0xff,4);
423    }
424    else
425    {
426        memcpy(camid, reader[ridx].hexserial+2,4);
427    }
428    cs_debug("[nagra-reader] using camid %s for dt08 calc",cs_hexdump (1,camid,4));
429   
430    // Calculate signature
431    memcpy (signature, static_dt08, 8);
432    memset (static_dt08 + 0, 0, 4);
433    memcpy (static_dt08 + 4, camid, 4);
434    Signature(sign2,IdeaCamKey,static_dt08,72);
435   
436    if (memcmp (signature, sign2, 8)==0)
437    {
438        has_dt08=1;
439        memcpy (plainDT08RSA, static_dt08+8, 64);
440        cs_debug("[nagra-reader] DT08 signature check ok");
441    }
442    else
443    {
444        has_dt08=0;
445        cs_debug("[nagra-reader] DT08 signature check nok");
446    }   
447}
448
449static void addProvider()
450{
451    int i;
452    int toadd=1;
453    for (i=0; i<reader[ridx].nprov; i++)
454    {
455        if ((cta_res[7]==reader[ridx].prid[i][2]) && (cta_res[8]==reader[ridx].prid[i][3]))
456        {
457            toadd = 0;
458        }
459    }
460    if (toadd)
461    {
462        reader[ridx].prid[reader[ridx].nprov][0]=0;
463        reader[ridx].prid[reader[ridx].nprov][1]=0;
464        reader[ridx].prid[reader[ridx].nprov][2]=cta_res[7];
465        reader[ridx].prid[reader[ridx].nprov][3]=cta_res[8];
466        memcpy(reader[ridx].sa[reader[ridx].nprov], reader[ridx].sa[0], 4);
467        reader[ridx].nprov+=1;
468    }
469}           
470
471static int ParseDataType(unsigned char dt)
472{
473    char ds[16], de[16];
474        ushort chid;
475    switch(dt) 
476    {
477        case IRDINFO:
478        {
479            reader[ridx].prid[0][0]=0;
480            reader[ridx].prid[0][1]=0;
481            reader[ridx].prid[0][2]=cta_res[7];
482            reader[ridx].prid[0][3]=cta_res[8];
483            if ( ((cta_res[7] == 0x34) && (cta_res[8] == 0x11)) || ((cta_res[7] == 0x04) && (cta_res[8] == 0x01))) //provider 3411, 0401 needs cw swap
484            {
485                cs_debug("[nagra-reader] detect provider with swap cw!");
486                swapCW=1;
487            }
488           
489            reader[ridx].prid[1][0]=0x00;
490            reader[ridx].prid[1][1]=0x00;
491            reader[ridx].prid[1][2]=0x00;
492            reader[ridx].prid[1][3]=0x00;
493            memcpy(reader[ridx].sa[1], reader[ridx].sa[0], 4);
494            reader[ridx].nprov+=1;
495                   
496            reader[ridx].caid[0] =(SYSTEM_NAGRA|cta_res[11]);
497                    memcpy(irdId,cta_res+14,4);
498                    cs_debug("[nagra-reader] type: NAGRA, caid: %04X, IRD ID: %s",reader[ridx].caid[0], cs_hexdump (1,irdId,4));
499                    cs_debug("[nagra-reader] ProviderID: %s",cs_hexdump (1,reader[ridx].prid[0],4));
500                    return OK;
501            }
502        case TIERS:
503            if ((cta_lr>33) && (chid=b2i(2, cta_res+11)))
504                {
505                    int id=(cta_res[7]*256)|cta_res[8];
506                    tier_date(b2i(2, cta_res+20)-0x7f7, ds, 15);
507                    tier_date(b2i(2, cta_res+13)-0x7f7, de, 15);
508                    cs_ri_log("|%04X|%04X    |%s  |%s  |", id,chid, ds, de);
509                    addProvider(); 
510                }
511            case 0x08:
512            case 0x88: if (cta_res[11] == 0x49) decryptDT08();             
513            default:
514                return OK;
515    }
516    return ERROR;
517}
518
519static int GetDataType(unsigned char dt, int len, int shots)
520{
521    int i;
522    for(i=0; i<shots; i++)
523    {
524        if(!do_cmd(0x22,0x03,0xA2,len,&dt))
525        {
526            cs_debug("[nagra-reader] failed to get datatype %02X",dt);
527            return ERROR;
528        }
529            if((cta_res[2]==0) && (dt != 0x08 || dt != 0x88)) return OK;
530            if(!ParseDataType(dt&0x0F)) return ERROR;
531            if ((dt != 0x08 || dt != 0x88) && (cta_res[11] == 0x49)) return OK; //got dt08 data
532            dt|=0x80; // get next item
533        }
534    return OK;
535}
536
537int nagra2_card_init(ATR newatr)
538{
539    get_atr;
540    memset(rom, 0, 15);
541    reader[ridx].nprov = 1;
542    memset(reader[ridx].hexserial, 0, 8); 
543    reader[ridx].caid[0]=SYSTEM_NAGRA;
544   
545    if (memcmp(atr+11, "DNASP", 5)==0)
546    {
547        cs_ri_log("detect native NAGRA card T1 protocol");
548        memcpy(rom,atr+11,15);
549    }
550    else if (memcmp(atr+11, "TIGER", 5)==0 || (memcmp(atr+11, "NCMED", 5)==0))
551    {
552        cs_ri_log("detect NAGRA tiger card");
553        memcpy(rom,atr+11,15);
554        is_tiger=1;
555    }
556    else if ((!memcmp(atr+4, "IRDETO", 6)) && ((atr[14]==0x03) && (atr[15]==0x84) && (atr[16]==0x55)))
557    {
558        cs_ri_log("detect Irdeto tunneled NAGRA card");
559        if(!reader[ridx].has_rsa)
560        {
561            cs_ri_log("switching back to Irdeto mode");
562            return ERROR;
563        }
564        cs_ri_log("using NAGRA mode");
565        is_pure_nagra=1;
566        if(!do_cmd(0x10,0x02,0x90,0x11,0))
567        {
568            cs_debug("[nagra-reader] get rom version failed");
569            return ERROR;
570        }
571        memcpy(rom,cta_res+2,15);
572    }
573    else return ERROR;
574
575    if (!is_tiger)
576    {
577        CamStateRequest();
578        if(!do_cmd(0x12,0x02,0x92,0x06,0)) 
579        {
580            cs_debug("[nagra-reader] get Serial failed");
581            return ERROR;
582        }
583        memcpy(reader[ridx].hexserial+2, cta_res+2, 4);
584        cs_debug("[nagra-reader] SER:  %s", cs_hexdump (1, reader[ridx].hexserial+2, 4));
585        memcpy(reader[ridx].sa[0], cta_res+2, 2);
586       
587        if(!GetDataType(DT01,0x0E,MAX_REC)) return ERROR;
588        cs_debug("[nagra-reader] DT01 DONE");
589        CamStateRequest();
590        if(!GetDataType(IRDINFO,0x39,MAX_REC)) return ERROR;
591        cs_debug("[nagra-reader] IRDINFO DONE");
592        CamStateRequest();
593        if(!GetDataType(CAMDATA,0x55,10)) return ERROR;
594        cs_debug("[nagra-reader] CAMDATA Done");
595        if(!GetDataType(0x04,0x44,MAX_REC)) return ERROR;
596        cs_debug("[nagra-reader] DT04 DONE");
597        CamStateRequest();
598       
599        if (!memcmp(rom+5, "181", 3)==0) //dt05 is not supported by rom181
600        {
601            cs_ri_log("-----------------------------------------");
602            cs_ri_log("|id  |tier    |valid from  |valid to    |");
603            cs_ri_log("+----+--------+------------+------------+");
604            if(!GetDataType(TIERS,0x57,MAX_REC)) return ERROR;
605            cs_ri_log("-----------------------------------------");
606            CamStateRequest();
607        }
608       
609        if(!GetDataType(DT06,0x16,MAX_REC)) return ERROR;
610        cs_debug("[nagra-reader] DT06 DONE");
611        CamStateRequest();
612    }
613    if (!NegotiateSessionKey())
614    {
615        cs_debug("[nagra-reader] NegotiateSessionKey failed");
616        return ERROR;
617    }
618    if ((reader[ridx].cardmhz != 368) && (is_pure_nagra==0))
619        cs_log("WARNING: For NAGRA2 cards you will have to set 'cardmhz = 368' in oscam.server");
620   
621    return OK;
622}
623
624int nagra2_card_info(void)
625{
626    int i;
627    cs_ri_log("ROM:    %c %c %c %c %c %c %c %c", rom[0], rom[1], rom[2],rom[3], rom[4], rom[5], rom[6], rom[7]);
628    cs_ri_log("REV:    %c %c %c %c %c %c", rom[9], rom[10], rom[11], rom[12], rom[13], rom[14]);
629    cs_ri_log("SER:    %s", cs_hexdump (1, reader[ridx].hexserial+2, 4));
630    cs_ri_log("CAID:   %04X",reader[ridx].caid[0]);
631    cs_ri_log("Prv.ID: %s(sysid)",cs_hexdump (1,reader[ridx].prid[0],4));
632    for (i=1; i<reader[ridx].nprov; i++)
633    {
634        cs_ri_log("Prv.ID: %s",cs_hexdump (1,reader[ridx].prid[i],4));
635    }
636    cs_log("[nagra-reader] ready for requests"); 
637    return OK;
638}
639
640void nagra2_post_process(void)
641{
642    if (!is_tiger)
643    {
644        CamStateRequest();
645        if RENEW_SESSIONKEY() NegotiateSessionKey();
646        if SENDDATETIME() DateTimeCMD();
647    }
648}
649
650int nagra2_do_ecm(ECM_REQUEST *er)
651{
652    if (!is_tiger)
653    {
654        int retry=0;
655        if(!do_cmd(er->ecm[3],er->ecm[4]+2,0x87,0x02, er->ecm+3+2)) 
656        {
657            cs_debug("[nagra-reader] nagra2_do_ecm failed, retry");
658            cs_sleepms(10);
659            if(!do_cmd(er->ecm[3],er->ecm[4]+2,0x87,0x02, er->ecm+3+2))
660            {
661                cs_debug("[nagra-reader] nagra2_do_ecm failed, retry failed!");
662                return ERROR;
663            }
664   
665        }
666        cs_sleepms(10);
667        while(!CamStateRequest() && retry < 3)
668        {
669            cs_debug("[nagra-reader] CamStateRequest failed, try: %d", retry);
670            retry++;
671                    cs_sleepms(10);
672        }
673        if (HAS_CW() && (do_cmd(0x1C,0x02,0x9C,0x36,NULL)))
674        {
675            unsigned char v[8];
676            memset(v,0,sizeof(v));
677            idea_cbc_encrypt(&cta_res[30],er->cw,8,&ksSession,v,IDEA_DECRYPT);
678            memset(v,0,sizeof(v));
679            idea_cbc_encrypt(&cta_res[4],er->cw+8,8,&ksSession,v,IDEA_DECRYPT);
680            if (swapCW==1)
681            {
682                cs_debug("[nagra-reader] swap cws");
683                    unsigned char tt[8];
684                    memcpy(&tt[0],&er->cw[0],8);
685                    memcpy(&er->cw[0],&er->cw[8],8);
686                memcpy(&er->cw[8],&tt[0],8);
687                }
688            return OK;
689        }
690    }
691    else
692    {
693        //check ECM prov id
694        if (memcmp(&reader[ridx].prid[0][2], er->ecm+5, 2))
695            return ERROR;
696   
697        //                  ecm_data: 80 30 89 D3 87 54 11 10 DA A6 0F 4B 92 05 34 00 ...
698        //serial_data: A0 CA 00 00 8C D3 8A 00 00 00 00 00 10 DA A6 0F .
699        unsigned char ecm_trim[150];
700        memset(ecm_trim, 0, 150);
701        memcpy(&ecm_trim[5], er->ecm+3+2+2, er->ecm[4]+2);
702        if(do_cmd(er->ecm[3],er->ecm[4]+5,0x53,0x16, ecm_trim)) 
703        {
704            if(cta_res[2] == 0x01)
705            {
706
707                unsigned char v[8];
708                memset(v,0,sizeof(v));
709                idea_cbc_encrypt(&cta_res[14],er->cw,8,&ksSession,v,IDEA_DECRYPT);
710                memset(v,0,sizeof(v));
711                idea_cbc_encrypt(&cta_res[6],er->cw+8,8,&ksSession,v,IDEA_DECRYPT);
712                return OK;
713            }
714            cs_debug("[nagra-reader] can't decode ecm");
715            return ERROR;
716        }
717    }
718    return ERROR;
719}
720
721int nagra2_get_emm_type(EMM_PACKET *ep) //returns TRUE if shared emm matches SA, unique emm matches serial, or global or unknown
722{
723  switch (ep->emm[0]) {
724        case 0x83:
725            memset(ep->hexserial,0,8);
726            ep->hexserial[0] = ep->emm[5];
727            ep->hexserial[1] = ep->emm[4];
728            ep->hexserial[2] = ep->emm[3];
729            ep->hexserial[3] = ep->emm[6];
730            if (ep->emm[7] == 0x10)
731                ep->type = SHARED;
732            else
733                ep->type = UNIQUE;
734            memcpy(ep->hexserial, ep->emm + 3, 6);
735            return (!memcmp (reader[ridx].hexserial, ep->hexserial, 4));
736        case 0x82:
737            ep->type = GLOBAL;
738            return TRUE;
739        default:
740            ep->type = UNKNOWN;
741            return TRUE;
742    }
743}
744
745int nagra2_do_emm(EMM_PACKET *ep)
746{
747    if (!is_tiger)
748    {
749        if(!do_cmd(ep->emm[8],ep->emm[9]+2,0x84,0x02,ep->emm+8+2))
750        {
751            cs_debug("[nagra-reader] nagra2_do_emm failed");
752            return ERROR;
753        }
754        // for slow t14 nagra cards, we must do additional timeout
755        if (is_pure_nagra==1) 
756        {
757            cs_sleepms(300);
758        }
759        cs_sleepms(250);
760        nagra2_post_process();
761    }
762    else
763    {
764        //check EMM prov id
765        if (memcmp(&reader[ridx].prid[0][2], ep->emm+10, 2))
766            return ERROR;
767   
768        //   emm_data: 82 70 8E 00 00 00 00 00 D3 87 8D 11 C0 F4 B1 27 2C 3D 25 94 ...
769        //serial_data: A0 CA 00 00 8C D3 8A 01 00 00 00 00 C0 F4 B1 27 2C 3D 25 94 ...
770        unsigned char emm_trim[150];
771        memset(emm_trim, 0, 150);
772        memcpy(&emm_trim[5], ep->emm+3+5+2+2, ep->emm[9]+2);
773        if(!do_cmd(ep->emm[8],ep->emm[9]+5,0x53,0x16, emm_trim))
774        {
775            cs_debug("[nagra-reader] nagra2_do_emm failed");
776            return ERROR;
777        }
778        cs_sleepms(300); 
779    }
780    return OK;
781}
Note: See TracBrowser for help on using the repository browser.