source: trunk/reader-nagra.c@ 1162

Last change on this file since 1162 was 1162, checked in by nightmann, 13 years ago

1.Fix some timming issues
2.remove some debug output
3.some changes in emm handling.
4.we dont care about providerID. Now you can also use 000000 as providerid in newcamd connection.
5.tivusat idea is not longer needed in oscam.server, we go an other way to check if rsa is ok. This should be a good compromise from the hint of neoen.
6.remove some not needed global vars

File size: 21.7 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))
533 {
534 swapCW=1;
535 }
536
537 reader[ridx].prid[1][0]=0x00;
538 reader[ridx].prid[1][1]=0x00;
539 reader[ridx].prid[1][2]=0x00;
540 reader[ridx].prid[1][3]=0x00;
541 memcpy(reader[ridx].sa[1], reader[ridx].sa[0], 4);
542 reader[ridx].nprov+=1;
543
544 reader[ridx].caid[0] =(SYSTEM_NAGRA|cta_res[11]);
545 //reader[ridx].caid[0] =0x1801;
546 memcpy(irdId,cta_res+14,4);
547 cs_debug("[nagra-reader] CAID: %04X, IRD ID: %s",reader[ridx].caid[0], cs_hexdump (1,irdId,4));
548 cs_debug("[nagra-reader] ProviderID: %s",cs_hexdump (1,reader[ridx].prid[0],4));
549 return 1;
550 }
551 case TIERS:
552 if ((cta_lr>33) && (chid=b2i(2, cta_res+11)))
553 {
554 int id=(cta_res[7]*256)|cta_res[8];
555 tier_date(b2i(2, cta_res+20)-0x7f7, ds, 15);
556 tier_date(b2i(2, cta_res+13)-0x7f7, de, 15);
557 cs_ri_log("|%04X|%04X |%s |%s |", id,chid, ds, de);
558 addProvider();
559 }
560 case 0x08:
561 case 0x88: if (cta_res[11] == 0x49) decryptDT08();
562 default:
563 return 1;
564 }
565 return 0;
566}
567
568int GetDataType(unsigned char dt, int len, int shots)
569{
570 int i;
571 for(i=0; i<shots; i++)
572 {
573 if(!do_cmd(0x22,0x03,0xA2,len,&dt))
574 {
575 cs_debug("[nagra-reader] failed to get datatype %02X",dt);
576 return 0;
577 }
578 if((cta_res[2]==0) && (dt != 0x08 || dt != 0x88)) return 1;
579 if(!ParseDataType(dt&0x0F)) return 0;
580 if ((dt != 0x08 || dt != 0x88) && (cta_res[11] == 0x49)) return 1; //got dt08 data
581 dt|=0x80; // get next item
582 }
583 return 1;
584}
585
586int nagra2_card_init(uchar *atr)
587{
588 memset(rom, 0, 15);
589 reader[ridx].nprov = 1;
590 memset(reader[ridx].hexserial, 0, 8);
591 reader[ridx].caid[0]=SYSTEM_NAGRA;
592
593 if (memcmp(atr+11, "DNASP", 5)==0)
594 {
595 if(SetIFS(0xFE) != 1) return 0;
596 cs_ri_log("[nagra-reader] detect native nagra card T1 protocol");
597 memcpy(rom,atr+11,15);
598 }
599 else if (memcmp(atr+11, "TIGER", 5)==0 || (memcmp(atr+11, "NCMED", 5)==0))
600 {
601 if(SetIFS(0xFE) != 1) return 0;
602 cs_ri_log("[nagra-reader] detect nagra tiger card");
603 memcpy(rom,atr+11,15);
604 is_tiger=1;
605 }
606 else if (!memcmp(atr+4, "IRDETO", 6))
607 {
608 cs_ri_log("[nagra-reader] detect Irdeto tunneled nagra card");
609 if(!reader[ridx].nagra_native) return 0;
610 cs_ri_log("[nagra-reader] using nagra mode");
611 is_pure_nagra=1;
612 if(!do_cmd(0x10,0x02,0x90,0x11,0))
613 {
614 cs_debug("[nagra-reader] get rom version failed");
615 return 0;
616 }
617 memcpy(rom,cta_res+2,15);
618 }
619 else return 0;
620
621 if (!is_tiger)
622 {
623 CamStateRequest();
624 if(!do_cmd(0x12,0x02,0x92,0x06,0))
625 {
626 cs_debug("[nagra-reader] get Serial failed");
627 return 0;
628 }
629 memcpy(reader[ridx].hexserial+2, cta_res+2, 4);
630 cs_debug("[nagra-reader] SER: %s", cs_hexdump (1, reader[ridx].hexserial+2, 4));
631 //memset(reader[ridx].sa[0], 0xff, 4);
632 //memcpy(reader[ridx].sa[0], cta_res+2, 2);
633
634 if(!GetDataType(DT01,0x0E,MAX_REC)) return 0;
635 cs_debug("[nagra-reader] DT01 DONE");
636 CamStateRequest();
637 if(!GetDataType(IRDINFO,0x39,MAX_REC)) return 0;
638 cs_debug("[nagra-reader] IRDINFO DONE");
639 CamStateRequest();
640 if(!GetDataType(CAMDATA,0x55,10)) return 0;
641 cs_debug("[nagra-reader] CAMDATA Done");
642 if(!GetDataType(0x04,0x44,MAX_REC)) return 0;
643 cs_debug("[nagra-reader] DT04 DONE");
644 CamStateRequest();
645
646 if (!memcmp(rom+5, "181", 3)==0) //dt05 is not supported by rom181
647 {
648 cs_ri_log("-----------------------------------------");
649 cs_ri_log("|id |tier |valid from |valid to |");
650 cs_ri_log("+----+--------+------------+------------+");
651 if(!GetDataType(TIERS,0x57,MAX_REC)) return 0;
652 cs_ri_log("-----------------------------------------");
653 CamStateRequest();
654 }
655
656 if(!GetDataType(DT06,0x16,MAX_REC)) return 0;
657 cs_debug("[nagra-reader] DT06 DONE");
658 CamStateRequest();
659 }
660 if (!NegotiateSessionKey())
661 {
662 cs_debug("[nagra-reader] NegotiateSessionKey failed");
663 return 0;
664 }
665
666 return 1;
667}
668
669int nagra2_card_info(void)
670{
671 int i;
672 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]);
673 cs_ri_log("REV: %c %c %c %c %c %c", rom[9], rom[10], rom[11], rom[12], rom[13], rom[14]);
674 cs_ri_log("SER: %s", cs_hexdump (1, reader[ridx].hexserial+2, 4));
675 cs_ri_log("CAID: %04X",reader[ridx].caid[0]);
676 cs_ri_log("Prv.ID: %s(sysid)",cs_hexdump (1,reader[ridx].prid[0],4));
677 for (i=1; i<reader[ridx].nprov; i++)
678 {
679 cs_ri_log("Prv.ID: %s",cs_hexdump (1,reader[ridx].prid[i],4));
680 }
681 cs_log("ready for requests");
682 return 1;
683}
684
685void nagra2_post_process(void)
686{
687 if (!is_tiger)
688 {
689 CamStateRequest();
690 cs_sleepms(10);
691 if RENEW_SESSIONKEY NegotiateSessionKey();
692 if SENDDATETIME DateTimeCMD();
693 }
694}
695
696int nagra2_do_ecm(ECM_REQUEST *er)
697{
698 if (!is_tiger)
699 {
700 int retry=0;
701 if(!do_cmd(er->ecm[3],er->ecm[4]+2,0x87,0x02, er->ecm+3+2))
702 {
703 cs_debug("[nagra-reader] nagra2_do_ecm failed, retry");
704 if(!do_cmd(er->ecm[3],er->ecm[4]+2,0x87,0x02, er->ecm+3+2))
705 {
706 cs_debug("[nagra-reader] nagra2_do_ecm failed");
707 return (0);
708 }
709
710 }
711 cs_sleepms(15);
712 while(!CamStateRequest() && retry < 5)
713 {
714 cs_debug("[nagra-reader] CamStateRequest failed, try: %d", retry);
715 retry++;
716 cs_sleepms(15);
717 }
718 cs_sleepms(15);
719 if (HAS_CW && do_cmd(0x1C,0x02,0x9C,0x36,NULL))
720 {
721 unsigned char v[8];
722 memset(v,0,sizeof(v));
723 idea_cbc_encrypt(&cta_res[30],er->cw,8,&ksSession,v,IDEA_DECRYPT);
724 memset(v,0,sizeof(v));
725 idea_cbc_encrypt(&cta_res[4],er->cw+8,8,&ksSession,v,IDEA_DECRYPT);
726 if (swapCW==1)
727 {
728 unsigned char tt[8];
729 memcpy(&tt[0],&er->cw[0],8);
730 memcpy(&er->cw[0],&er->cw[8],8);
731 memcpy(&er->cw[8],&tt[0],8);
732 }
733 return (1);
734 }
735 }
736 else
737 {
738 // ecm_data: 80 30 89 D3 87 54 11 10 DA A6 0F 4B 92 05 34 00 ...
739 //serial_data: A0 CA 00 00 8C D3 8A 00 00 00 00 00 10 DA A6 0F .
740 unsigned char ecm_trim[150];
741 memset(ecm_trim, 0, 150);
742 memcpy(&ecm_trim[5], er->ecm+3+2+2, er->ecm[4]+2);
743 if(do_cmd(er->ecm[3],er->ecm[4]+5,0x53,0x16, ecm_trim))
744 {
745 if(cta_res[2] == 0x01)
746 {
747
748 unsigned char v[8];
749 memset(v,0,sizeof(v));
750 idea_cbc_encrypt(&cta_res[14],er->cw,8,&ksSession,v,IDEA_DECRYPT);
751 memset(v,0,sizeof(v));
752 idea_cbc_encrypt(&cta_res[6],er->cw+8,8,&ksSession,v,IDEA_DECRYPT);
753 return (1);
754 }
755 cs_debug("[nagra-reader] can't decode ecm");
756 return (0);
757 }
758 }
759 return(0);
760}
761
762int nagra2_do_emm(EMM_PACKET *ep)
763{
764 cs_debug("[nagra-reader] do_emm #########################################################");
765 cs_debug("[nagra-reader] do_emm #########################################################");
766 cs_debug("[nagra-reader] do_emm #########################################################");
767 cs_debug("[nagra-reader] do_emm #########################################################");
768 cs_debug("[nagra-reader] do_emm #########################################################");
769 if(!do_cmd(ep->emm[8],ep->emm[9]+2,0x84,0x02,ep->emm+8+2))
770 {
771 cs_debug("[nagra-reader] nagra2_do_emm failed");
772 return (0);
773 }
774 cs_sleepms(3000);
775 nagra2_post_process();
776 return 1;
777}
Note: See TracBrowser for help on using the repository browser.