source: trunk/reader-nagra.c@ 1196

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