source: branches/smartreader/reader-nagra.c@ 1186

Last change on this file since 1186 was 1186, checked in by rorothetroll, 12 years ago

resync with trunk. Old smartreader code is gone (and will soon be gone from trunk). I'm restarting from trunk to do a clean implementation of the samrtreader support using libusb.

File size: 21.6 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 sessi1[8];
195 unsigned char sessi2[8];
196 unsigned char tmp[104];
197 unsigned char tmp1[8];
198 unsigned char idea_sig[16];
199 unsigned char random[88] = {0x51,0xd0,0xcc,0x4a,0x51,0xbc,0x4f,0xa4,0x7d,0x44,0xa9,0xa8,0x97,0x13,0x01,0x63,
200 0x8f,0xaf,0x86,0x60,0x7c,0xe3,0xee,0x29,0xca,0x13,0x09,0x44,0x83,0x48,0x17,0x8b,
201 0x88,0xa6,0x64,0x20,0x22,0x2b,0x04,0x50,0xd8,0x15,0x9c,0x50,0x09,0x7c,0x6a,0x5d,
202 0xa0,0xb3,0xb0,0x11,0xa2,0x15,0x00,0x58,0xae,0x4b,0xe7,0xb0,0x06,0xa0,0x1d,0xe0,
203 0x53,0x58,0x6a,0xf0,0x60,0x51,0x71,0xdb,0xe7,0x7c,0xf7,0x1b,0x37,0x9d,0x20,0xf8,
204 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
205
206 if(!do_cmd(0xd1,0x02,0x51,0xd2,NULL))
207 {
208 cs_debug("[nagra-reader] CMD$D1 failed");
209 return 0;
210 }
211
212 BN_CTX *ctx = BN_CTX_new();
213 BIGNUM *bnN = BN_CTX_get(ctx);
214 BIGNUM *bnE = BN_CTX_get(ctx);
215 BIGNUM *bnCT = BN_CTX_get(ctx);
216 BIGNUM *bnPT = BN_CTX_get(ctx);
217 BN_bin2bn(reader[ridx].rsa_mod, 120, bnN);
218 BN_bin2bn(vFixed+4, 1, bnE);
219 BN_bin2bn(&cta_res[90], 120, bnCT);
220 BN_mod_exp(bnPT, bnCT, bnE, bnN, ctx);
221 memset(parte_fija, 0, 120);
222 BN_bn2bin(bnPT, parte_fija + (120-BN_num_bytes(bnPT)));
223 BN_CTX_end(ctx);
224 BN_CTX_free (ctx);
225
226 cs_debug("[nagra-reader] ---------- SIG CHECK ---------------------");
227 memset(tmp,0, 104);
228 memcpy(tmp+4, parte_fija+11, 100);
229 memset(idea_sig, 0x37, 16);
230 Signature(sign1, idea_sig, tmp, 104);
231 cs_debug("[nagra-reader] sign1: %s", cs_hexdump (0, sign1, 8));
232 cs_debug("[nagra-reader] sign2: %s", cs_hexdump (0, parte_fija+111, 8));
233 if (!memcmp (parte_fija+111, sign1, 8)==0)
234 {
235 cs_debug("[nagra-reader] signature check nok");
236 cs_debug("[nagra-reader] ------------------------------------------");
237 return 0;
238 }
239 cs_debug("[nagra-reader] signature check ok");
240 cs_debug("[nagra-reader] ------------------------------------------");
241
242 memcpy(reader[ridx].hexserial, parte_fija+15, 4);
243 memcpy(irdId, parte_fija+19, 4);
244 memcpy(d1_rsa_modulo,parte_fija+23,88);
245
246 ReverseMem(cta_res+2, 88);
247 BN_CTX *ctx1 = BN_CTX_new();
248 BIGNUM *bnN1 = BN_CTX_get(ctx1);
249 BIGNUM *bnE1 = BN_CTX_get(ctx1);
250 BIGNUM *bnCT1 = BN_CTX_get(ctx1);
251 BIGNUM *bnPT1 = BN_CTX_get(ctx1);
252 BN_bin2bn(d1_rsa_modulo, 88, bnN1);
253 BN_bin2bn(vFixed+4, 1, bnE1);
254 BN_bin2bn(cta_res+2, 88, bnCT1);
255 BN_mod_exp(bnPT1, bnCT1, bnE1, bnN1, ctx1);
256 memset(parte_variable, 0, 88);
257 BN_bn2bin(bnPT1, parte_variable + (88-BN_num_bytes(bnPT1)));
258 BN_CTX_end(ctx1);
259 BN_CTX_free (ctx1);
260
261 reader[ridx].prid[0][0]=0x00;
262 reader[ridx].prid[0][1]=0x00;
263 reader[ridx].prid[0][2]=parte_variable[73];
264 reader[ridx].prid[0][3]=parte_variable[74];
265 reader[ridx].caid[0] =(SYSTEM_NAGRA|parte_variable[76]);
266 memcpy(sessi1,&parte_variable[79],8);
267 cs_ri_log("[nagra-reader] CAID: %04X, IRD ID: %s",reader[ridx].caid[0], cs_hexdump (1,irdId,4));
268 cs_ri_log("[nagra-reader] ProviderID: %s",cs_hexdump (1,reader[ridx].prid[0],4));
269
270 memcpy(sessi2,&random[72], 8);
271 memset(tmp1,0,8);
272 memcpy(tmp1, random+72,8);
273 ReverseMem(tmp1, 8); //byteflop last 8 bytes of random data
274 memcpy(random+72, tmp1,8); // insert back the byteflop data
275
276 memset(tmp1,0,8);
277 memcpy(tmp1, sessi1,8);
278 ReverseMem(tmp1, 8); // byteflop sessi1 one from rsa variabled part
279 memcpy(random+80,tmp1,8); // and attach him to random data
280
281
282 BN_CTX *ctx3 = BN_CTX_new();
283 BIGNUM *bnN3 = BN_CTX_get(ctx3);
284 BIGNUM *bnE3 = BN_CTX_get(ctx3);
285 BIGNUM *bnCT3 = BN_CTX_get(ctx3);
286 BIGNUM *bnPT3 = BN_CTX_get(ctx3);
287 BN_bin2bn(d1_rsa_modulo, 88, bnN3);
288 BN_bin2bn(vFixed+4, 1, bnE3);
289 BN_bin2bn(random, 88, bnCT3);
290 BN_mod_exp(bnPT3, bnCT3, bnE3, bnN3, ctx3);
291 memset(d2_data, 0, 88);
292 BN_bn2bin(bnPT3, d2_data + (88-BN_num_bytes(bnPT3)));
293 BN_CTX_end(ctx3);
294 BN_CTX_free (ctx3);
295 ReverseMem(d2_data, 88);
296
297 if(!do_cmd(0xd2,0x5a,0x52,0x03, d2_data))
298 {
299 cs_debug("[nagra-reader] CMD$D2 failed");
300 return 0;
301 }
302 if (cta_res[2] == 0x00)
303 {
304 memcpy(sessi,sessi1,8); memcpy(sessi+8,sessi2,8);
305 IDEA_KEY_SCHEDULE ks;
306 idea_set_encrypt_key(sessi,&ks);
307 idea_set_decrypt_key(&ks,&ksSession);
308 cs_ri_log("[nagra-reader] session key: %s", cs_hexdump(1, sessi, 16));
309 return 1;
310 }
311 cs_ri_log("Negotiate sessionkey was not successfull! Please check tivusat rsa key");
312 return 0;
313
314}
315
316int NegotiateSessionKey(void)
317{
318 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};
319 unsigned char negot[64];
320 unsigned char tmp[64];
321 unsigned char idea1[16];
322 unsigned char idea2[16];
323 unsigned char sign1[8];
324 unsigned char sign2[8];
325
326 if (is_tiger)
327 {
328 if (!NegotiateSessionKey_Tiger())
329 {
330 cs_debug("[nagra-reader] NegotiateSessionKey_Tiger failed");
331 return 0;
332 }
333 return 1;
334 }
335 if (!has_dt08) // if we have no valid dt08 calc then we use rsa from config and hexserial for calc of sessionkey
336 {
337 memcpy(plainDT08RSA, reader[ridx].rsa_mod, 64);
338 memcpy(signature,reader[ridx].nagra_boxkey, 8);
339 }
340 if(!do_cmd(0x2a,0x02,0xaa,0x42,NULL))
341 {
342 cs_debug("[nagra-reader] CMD$2A failed");
343 return 0;
344 }
345
346 // RSA decrypt of cmd$2a data, result is stored in "negot"
347 ReverseMem(cta_res+2, 64);
348 //cs_debug("[nagra-reader] plainDT08RSA: %s", cs_hexdump (1, plainDT08RSA, 32));
349 //cs_debug("[nagra-reader] plainDT08RSA: %s", cs_hexdump (1, &plainDT08RSA[32], 32));
350 unsigned char vFixed[] = {0,1,2,3};
351 BN_CTX *ctx = BN_CTX_new();
352 BIGNUM *bnN = BN_CTX_get(ctx);
353 BIGNUM *bnE = BN_CTX_get(ctx);
354 BIGNUM *bnCT = BN_CTX_get(ctx);
355 BIGNUM *bnPT = BN_CTX_get(ctx);
356 BN_bin2bn(plainDT08RSA, 64, bnN);
357 BN_bin2bn(vFixed+3, 1, bnE);
358 BN_bin2bn(cta_res+2, 64, bnCT);
359 BN_mod_exp(bnPT, bnCT, bnE, bnN, ctx);
360 memset(negot, 0, 64);
361 BN_bn2bin(bnPT, negot + (64-BN_num_bytes(bnPT)));
362 //cs_debug("[nagra-reader] DT08 decrypted $2a data: %s", cs_hexdump (1, negot, 32));
363 //cs_debug("[nagra-reader] DT08 decrypted $2a data: %s", cs_hexdump (1, &negot[32], 32));
364
365 memcpy(tmp, negot, 64);
366 ReverseMem(tmp, 64);
367
368 // build sessionkey
369 // 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
370 memcpy(idea1, signature, 8);
371 memcpy(idea1+8, reader[ridx].hexserial+2, 4);
372 idea1[12] = ~reader[ridx].hexserial[2]; idea1[13] = ~reader[ridx].hexserial[3]; idea1[14] = ~reader[ridx].hexserial[4]; idea1[15] = ~reader[ridx].hexserial[5];
373
374 Signature(sign1, idea1, tmp, 32);
375 memcpy(idea2,sign1,8); memcpy(idea2+8,sign1,8);
376 Signature(sign2, idea2, tmp, 32);
377 memcpy(sessi,sign1,8); memcpy(sessi+8,sign2,8);
378
379 // prepare cmd$2b data
380 BN_bin2bn(negot, 64, bnCT);
381 BN_mod_exp(bnPT, bnCT, bnE, bnN, ctx);
382 memset(cmd2b+10, 0, 64);
383 BN_bn2bin(bnPT, cmd2b+10 + (64-BN_num_bytes(bnPT)));
384 BN_CTX_end(ctx);
385 BN_CTX_free (ctx);
386 ReverseMem(cmd2b+10, 64);
387
388 IDEA_KEY_SCHEDULE ks;
389 idea_set_encrypt_key(sessi,&ks);
390 idea_set_decrypt_key(&ks,&ksSession);
391
392 if(!do_cmd(0x2b,0x42,0xab,0x02, cmd2b+10))
393 {
394 cs_debug("[nagra-reader] CMD$2B failed");
395 return 0;
396 }
397
398 cs_debug("[nagra-reader] session key: %s", cs_hexdump(1, sessi, 16));
399
400 if (!CamStateRequest())
401 {
402 cs_debug("[nagra-reader] CamStateRequest failed");
403 return 0;
404 }
405 if SENDDATETIME
406 {
407 DateTimeCMD();
408 }
409 if RENEW_SESSIONKEY
410 {
411 cs_ri_log("Negotiate sessionkey was not successfull! Please check rsa key and boxkey");
412 return 0;
413 }
414
415 return 1;
416}
417
418void decryptDT08(void)
419{
420
421 unsigned char vFixed[] = {0,1,2,3};
422 unsigned char v[72];
423 unsigned char buf[72];
424 unsigned char sign2[8];
425 unsigned char static_dt08[73];
426 unsigned char camid[4];
427 int i, n;
428 BN_CTX *ctx;
429 BIGNUM *bn_mod, *bn_exp, *bn_data, *bn_res;
430
431 memcpy(static_dt08, &cta_res[12], 73);
432 // decrypt RSA Part of dt08
433 bn_mod = BN_new ();
434 bn_exp = BN_new ();
435 bn_data = BN_new ();
436 bn_res = BN_new ();
437 ctx= BN_CTX_new();
438 if (ctx == NULL) cs_debug("[nagra-reader] RSA Error in dt08 decrypt");
439 ReverseMem(static_dt08+1, 64);
440 BN_bin2bn (reader[ridx].rsa_mod, 64, bn_mod); // rsa modulus
441 BN_bin2bn (vFixed+3, 1, bn_exp); // exponent
442 BN_bin2bn (static_dt08+1, 64, bn_data);
443 BN_mod_exp (bn_res, bn_data, bn_exp, bn_mod, ctx);
444 memset (static_dt08+1, 0, 64);
445 n = BN_bn2bin (bn_res, static_dt08+1);
446 BN_CTX_free (ctx);
447 ReverseMem(static_dt08+1, n);
448
449 // RSA data can never be bigger than the modulo
450 static_dt08[64] |= static_dt08[0] & 0x80;
451
452 // IdeaCamKey
453 memcpy (&IdeaCamKey[0], reader[ridx].nagra_boxkey, 8);
454 memcpy (&IdeaCamKey[8], irdId, 4);
455 for (i = 0; i < 4; i++)
456 IdeaCamKey[12 + i] = ~irdId[i];
457
458 // now IDEA decrypt
459 IDEA_KEY_SCHEDULE ks;
460 idea_set_encrypt_key(IdeaCamKey,&ks);
461 idea_set_decrypt_key(&ks,&ksSession);
462 memcpy (&buf[0], static_dt08+1, 64);
463 memcpy (&buf[64], static_dt08+65, 8);
464 memset(v,0,sizeof(v));
465 memset(static_dt08,0,sizeof(static_dt08));
466 idea_cbc_encrypt(buf,static_dt08,72,&ksSession,v,IDEA_DECRYPT);
467
468 if (swapCW==1)
469 {
470 memset(camid,0xff,4);
471 }
472 else
473 {
474 memcpy(camid, reader[ridx].hexserial+2,4);
475 }
476 cs_debug("[nagra-reader] using camid %s for dt08 calc",cs_hexdump (1,camid,4));
477
478 // Calculate signature
479 memcpy (signature, static_dt08, 8);
480 memset (static_dt08 + 0, 0, 4);
481 memcpy (static_dt08 + 4, camid, 4);
482 Signature(sign2,IdeaCamKey,static_dt08,72);
483
484 if (memcmp (signature, sign2, 8)==0)
485 {
486 has_dt08=1;
487 memcpy (plainDT08RSA, static_dt08+8, 64);
488 cs_debug("[nagra-reader] DT08 signature check ok");
489 }
490 else
491 {
492 has_dt08=0;
493 cs_debug("[nagra-reader] DT08 signature check nok");
494 }
495}
496
497void addProvider()
498{
499 int i;
500 int toadd=1;
501 for (i=0; i<reader[ridx].nprov; i++)
502 {
503 if ((cta_res[7]==reader[ridx].prid[i][2]) && (cta_res[8]==reader[ridx].prid[i][3]))
504 {
505 toadd = 0;
506 }
507 }
508 if (toadd)
509 {
510 reader[ridx].prid[reader[ridx].nprov][0]=0;
511 reader[ridx].prid[reader[ridx].nprov][1]=0;
512 reader[ridx].prid[reader[ridx].nprov][2]=cta_res[7];
513 reader[ridx].prid[reader[ridx].nprov][3]=cta_res[8];
514 memcpy(reader[ridx].sa[reader[ridx].nprov], reader[ridx].sa[0], 4);
515 reader[ridx].nprov+=1;
516 }
517}
518
519int ParseDataType(unsigned char dt)
520{
521 char ds[16], de[16];
522 ushort chid;
523 switch(dt)
524 {
525 case IRDINFO:
526 {
527 reader[ridx].prid[0][0]=0;
528 reader[ridx].prid[0][1]=0;
529 reader[ridx].prid[0][2]=cta_res[7];
530 reader[ridx].prid[0][3]=cta_res[8];
531 memcpy(reader[ridx].sa[0], reader[ridx].sa[0], 4);
532 if ( ((cta_res[7] == 0x34) && (cta_res[8] == 0x11)) || ((cta_res[7] == 0x04) && (cta_res[8] == 0x01))) //provider 3411, 0401 needs cw swap
533 {
534 cs_debug("[nagra-reader] detect provider with swap cw!");
535 swapCW=1;
536 }
537
538 reader[ridx].prid[1][0]=0x00;
539 reader[ridx].prid[1][1]=0x00;
540 reader[ridx].prid[1][2]=0x00;
541 reader[ridx].prid[1][3]=0x00;
542 memcpy(reader[ridx].sa[1], reader[ridx].sa[0], 4);
543 reader[ridx].nprov+=1;
544
545 reader[ridx].caid[0] =(SYSTEM_NAGRA|cta_res[11]);
546 //reader[ridx].caid[0] =0x1801;
547 memcpy(irdId,cta_res+14,4);
548 cs_debug("[nagra-reader] CAID: %04X, IRD ID: %s",reader[ridx].caid[0], cs_hexdump (1,irdId,4));
549 cs_debug("[nagra-reader] ProviderID: %s",cs_hexdump (1,reader[ridx].prid[0],4));
550 return 1;
551 }
552 case TIERS:
553 if ((cta_lr>33) && (chid=b2i(2, cta_res+11)))
554 {
555 int id=(cta_res[7]*256)|cta_res[8];
556 tier_date(b2i(2, cta_res+20)-0x7f7, ds, 15);
557 tier_date(b2i(2, cta_res+13)-0x7f7, de, 15);
558 cs_ri_log("|%04X|%04X |%s |%s |", id,chid, ds, de);
559 addProvider();
560 }
561 case 0x08:
562 case 0x88: if (cta_res[11] == 0x49) decryptDT08();
563 default:
564 return 1;
565 }
566 return 0;
567}
568
569int GetDataType(unsigned char dt, int len, int shots)
570{
571 int i;
572 for(i=0; i<shots; i++)
573 {
574 if(!do_cmd(0x22,0x03,0xA2,len,&dt))
575 {
576 cs_debug("[nagra-reader] failed to get datatype %02X",dt);
577 return 0;
578 }
579 if((cta_res[2]==0) && (dt != 0x08 || dt != 0x88)) return 1;
580 if(!ParseDataType(dt&0x0F)) return 0;
581 if ((dt != 0x08 || dt != 0x88) && (cta_res[11] == 0x49)) return 1; //got dt08 data
582 dt|=0x80; // get next item
583 }
584 return 1;
585}
586
587int nagra2_card_init(uchar *atr)
588{
589 memset(rom, 0, 15);
590 reader[ridx].nprov = 1;
591 memset(reader[ridx].hexserial, 0, 8);
592 reader[ridx].caid[0]=SYSTEM_NAGRA;
593
594 if (memcmp(atr+11, "DNASP", 5)==0)
595 {
596 if(SetIFS(0xFE) != 1) return 0;
597 cs_ri_log("[nagra-reader] detect native nagra card T1 protocol");
598 memcpy(rom,atr+11,15);
599 }
600 else if (memcmp(atr+11, "TIGER", 5)==0 || (memcmp(atr+11, "NCMED", 5)==0))
601 {
602 if(SetIFS(0xFE) != 1) return 0;
603 cs_ri_log("[nagra-reader] detect nagra tiger card");
604 memcpy(rom,atr+11,15);
605 is_tiger=1;
606 }
607 else if (!memcmp(atr+4, "IRDETO", 6))
608 {
609 cs_ri_log("[nagra-reader] detect Irdeto tunneled nagra card");
610 if(!reader[ridx].nagra_native) return 0;
611 cs_ri_log("[nagra-reader] using nagra mode");
612 is_pure_nagra=1;
613 if(!do_cmd(0x10,0x02,0x90,0x11,0))
614 {
615 cs_debug("[nagra-reader] get rom version failed");
616 return 0;
617 }
618 memcpy(rom,cta_res+2,15);
619 }
620 else return 0;
621
622 if (!is_tiger)
623 {
624 CamStateRequest();
625 if(!do_cmd(0x12,0x02,0x92,0x06,0))
626 {
627 cs_debug("[nagra-reader] get Serial failed");
628 return 0;
629 }
630 memcpy(reader[ridx].hexserial+2, cta_res+2, 4);
631 cs_debug("[nagra-reader] SER: %s", cs_hexdump (1, reader[ridx].hexserial+2, 4));
632 //memset(reader[ridx].sa[0], 0xff, 4);
633 memcpy(reader[ridx].sa[0], cta_res+2, 2);
634
635 if(!GetDataType(DT01,0x0E,MAX_REC)) return 0;
636 cs_debug("[nagra-reader] DT01 DONE");
637 CamStateRequest();
638 if(!GetDataType(IRDINFO,0x39,MAX_REC)) return 0;
639 cs_debug("[nagra-reader] IRDINFO DONE");
640 CamStateRequest();
641 if(!GetDataType(CAMDATA,0x55,10)) return 0;
642 cs_debug("[nagra-reader] CAMDATA Done");
643 if(!GetDataType(0x04,0x44,MAX_REC)) return 0;
644 cs_debug("[nagra-reader] DT04 DONE");
645 CamStateRequest();
646
647 if (!memcmp(rom+5, "181", 3)==0) //dt05 is not supported by rom181
648 {
649 cs_ri_log("-----------------------------------------");
650 cs_ri_log("|id |tier |valid from |valid to |");
651 cs_ri_log("+----+--------+------------+------------+");
652 if(!GetDataType(TIERS,0x57,MAX_REC)) return 0;
653 cs_ri_log("-----------------------------------------");
654 CamStateRequest();
655 }
656
657 if(!GetDataType(DT06,0x16,MAX_REC)) return 0;
658 cs_debug("[nagra-reader] DT06 DONE");
659 CamStateRequest();
660 }
661 if (!NegotiateSessionKey())
662 {
663 cs_debug("[nagra-reader] NegotiateSessionKey failed");
664 return 0;
665 }
666
667 return 1;
668}
669
670int nagra2_card_info(void)
671{
672 int i;
673 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]);
674 cs_ri_log("REV: %c %c %c %c %c %c", rom[9], rom[10], rom[11], rom[12], rom[13], rom[14]);
675 cs_ri_log("SER: %s", cs_hexdump (1, reader[ridx].hexserial+2, 4));
676 cs_ri_log("CAID: %04X",reader[ridx].caid[0]);
677 cs_ri_log("Prv.ID: %s(sysid)",cs_hexdump (1,reader[ridx].prid[0],4));
678 for (i=1; i<reader[ridx].nprov; i++)
679 {
680 cs_ri_log("Prv.ID: %s",cs_hexdump (1,reader[ridx].prid[i],4));
681 }
682 cs_log("ready for requests");
683 return 1;
684}
685
686void nagra2_post_process(void)
687{
688 if (!is_tiger)
689 {
690 CamStateRequest();
691 cs_sleepms(10);
692 if RENEW_SESSIONKEY NegotiateSessionKey();
693 if SENDDATETIME DateTimeCMD();
694 }
695}
696
697int nagra2_do_ecm(ECM_REQUEST *er)
698{
699 if (!is_tiger)
700 {
701 int retry=0;
702 if(!do_cmd(er->ecm[3],er->ecm[4]+2,0x87,0x02, er->ecm+3+2))
703 {
704 cs_debug("[nagra-reader] nagra2_do_ecm failed, retry");
705 if(!do_cmd(er->ecm[3],er->ecm[4]+2,0x87,0x02, er->ecm+3+2))
706 {
707 cs_debug("[nagra-reader] nagra2_do_ecm failed");
708 return (0);
709 }
710
711 }
712 cs_sleepms(15);
713 while(!CamStateRequest() && retry < 5)
714 {
715 cs_debug("[nagra-reader] CamStateRequest failed, try: %d", retry);
716 retry++;
717 cs_sleepms(15);
718 }
719 cs_sleepms(10);
720 if (HAS_CW && do_cmd(0x1C,0x02,0x9C,0x36,NULL))
721 {
722 unsigned char v[8];
723 memset(v,0,sizeof(v));
724 idea_cbc_encrypt(&cta_res[30],er->cw,8,&ksSession,v,IDEA_DECRYPT);
725 memset(v,0,sizeof(v));
726 idea_cbc_encrypt(&cta_res[4],er->cw+8,8,&ksSession,v,IDEA_DECRYPT);
727 if (swapCW==1)
728 {
729 cs_debug("[nagra-reader] swapCW");
730 unsigned char tt[8];
731 memcpy(&tt[0],&er->cw[0],8);
732 memcpy(&er->cw[0],&er->cw[8],8);
733 memcpy(&er->cw[8],&tt[0],8);
734 }
735 return (1);
736 }
737 }
738 else
739 {
740 // ecm_data: 80 30 89 D3 87 54 11 10 DA A6 0F 4B 92 05 34 00 ...
741 //serial_data: A0 CA 00 00 8C D3 8A 00 00 00 00 00 10 DA A6 0F .
742 unsigned char ecm_trim[150];
743 memset(ecm_trim, 0, 150);
744 memcpy(&ecm_trim[5], er->ecm+3+2+2, er->ecm[4]+2);
745 if(do_cmd(er->ecm[3],er->ecm[4]+5,0x53,0x16, ecm_trim))
746 {
747 if(cta_res[2] == 0x01)
748 {
749
750 unsigned char v[8];
751 memset(v,0,sizeof(v));
752 idea_cbc_encrypt(&cta_res[14],er->cw,8,&ksSession,v,IDEA_DECRYPT);
753 memset(v,0,sizeof(v));
754 idea_cbc_encrypt(&cta_res[6],er->cw+8,8,&ksSession,v,IDEA_DECRYPT);
755 return (1);
756 }
757 cs_debug("[nagra-reader] can't decode ecm");
758 return (0);
759 }
760 }
761 return(0);
762}
763
764int nagra2_do_emm(EMM_PACKET *ep)
765{
766 cs_debug("[nagra-reader] do_emm #########################################################");
767 cs_debug("[nagra-reader] do_emm #########################################################");
768 if(!do_cmd(ep->emm[8],ep->emm[9]+2,0x84,0x02,ep->emm+8+2))
769 {
770 cs_debug("[nagra-reader] nagra2_do_emm failed");
771 return (0);
772 }
773 cs_sleepms(300);
774 nagra2_post_process();
775 return 1;
776}
Note: See TracBrowser for help on using the repository browser.