source: trunk/reader-nagra.c@ 4149

Last change on this file since 4149 was 4141, checked in by dingo35, 13 years ago

all: simplify debug system, add D_DVBAPI = -d128, eliminate cs_ptyp which complicates stuff unnecc

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