Changeset 5441
- Timestamp:
- 06/20/11 13:15:53 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/reader-viaccess.c
r5368 r5441 3 3 4 4 struct via_date { 5 6 7 8 9 10 11 5 uint16_t day_s : 5; 6 uint16_t month_s : 4; 7 uint16_t year_s : 7; 8 9 uint16_t day_e : 5; 10 uint16_t month_e : 4; 11 uint16_t year_e : 7; 12 12 }; 13 13 14 14 static void parse_via_date(const uchar *buf, struct via_date *vd, int32_t fend) 15 15 { 16 17 18 19 20 21 22 23 24 25 26 27 28 29 16 uint16_t date; 17 18 date = (buf[0]<<8) | buf[1]; 19 vd->day_s = date & 0x1f; 20 vd->month_s = (date>>5) & 0x0f; 21 vd->year_s = (date>>9) & 0x7f; 22 23 if( fend ) 24 { 25 date = (buf[2]<<8) | buf[3]; 26 vd->day_e = date & 0x1f; 27 vd->month_e = (date>>5) & 0x0f; 28 vd->year_e = (date>>9) & 0x7f; 29 } 30 30 } 31 31 32 32 static void show_class(struct s_reader * reader, const char *p, const uchar *b, int32_t l) 33 33 { 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 else54 55 56 57 34 int32_t i, j; 35 36 // b -> via date (4 bytes) 37 b+=4; 38 l-=4; 39 40 j=l-1; 41 for (; j>=0; j--) 42 for (i=0; i<8; i++) 43 if (b[j] & (1 << (i&7))) 44 { 45 uchar cls; 46 struct via_date vd; 47 parse_via_date(b-4, &vd, 1); 48 cls=(l-(j+1))*8+i; 49 if (p) 50 cs_log("%sclass: %02X, expiry date: %04d/%02d/%02d - %04d/%02d/%02d", p, cls, 51 vd.year_s+1980, vd.month_s, vd.day_s, 52 vd.year_e+1980, vd.month_e, vd.day_e); 53 else 54 cs_ri_log(reader, "class: %02X, expiry date: %04d/%02d/%02d - %04d/%02d/%02d", cls, 55 vd.year_s+1980, vd.month_s, vd.day_s, 56 vd.year_e+1980, vd.month_e, vd.day_e); 57 } 58 58 } 59 59 60 60 static void show_subs(struct s_reader * reader, const uchar *emm) 61 61 { 62 63 64 65 66 67 68 69 /*70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 */95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 62 // emm -> A9, A6, B6 63 64 switch( emm[0] ) 65 { 66 case 0xA9: 67 show_class(reader, "nano A9: ", emm+2, emm[1]); 68 break; 69 /* 70 { 71 int32_t i, j, byts; 72 const uchar *oemm; 73 74 oemm = emm; 75 byts = emm[1]-4; 76 emm+=6; 77 78 j=byts-1; 79 for( ; j>=0; j-- ) 80 for( i=0; i<8; i++ ) 81 if( emm[j] & (1 << (i&7)) ) 82 { 83 uchar cls; 84 struct via_date vd; 85 parse_via_date(emm-4, &vd, 1); 86 cls=(byts-(j+1))*8+i; 87 cs_log("%sclass %02X: expiry date: %02d/%02d/%04d - %02d/%02d/%04d", 88 fnano?"nano A9: ":"", cls, 89 vd.day_s, vd.month_s, vd.year_s+1980, 90 vd.day_e, vd.month_e, vd.year_e+1980); 91 } 92 break; 93 } 94 */ 95 case 0xA6: 96 { 97 char szGeo[256]; 98 99 memset(szGeo, 0, 256); 100 strncpy(szGeo, (char *)emm+2, emm[1]); 101 cs_log("[viaccess-reader] nano A6: geo %s", szGeo); 102 break; 103 } 104 case 0xB6: 105 { 106 uchar m; // modexp 107 struct via_date vd; 108 109 m=emm[emm[1]+1]; 110 parse_via_date(emm+2, &vd, 0); 111 cs_log("[viaccess-reader] nano B6: modexp %d%d%d%d%d%d: %02d/%02d/%04d", (m&0x20)?1:0, 112 (m&0x10)?1:0,(m&0x08)?1:0,(m&0x04)?1:0,(m&0x02)?1:0,(m&0x01)?1:0, 113 vd.day_s, vd.month_s, vd.year_s+1980); 114 break; 115 } 116 } 117 117 } 118 118 119 119 static int32_t chk_prov(struct s_reader * reader, uchar *id, uchar keynr) 120 120 { 121 122 123 124 125 126 127 121 int32_t i, j, rc; 122 for (rc=i=0; (!rc) && (i<reader->nprov); i++) 123 if(!memcmp(&reader->prid[i][1], id, 3)) 124 for (j=0; (!rc) && (j<16); j++) 125 if (reader->availkeys[i][j]==keynr) 126 rc=1; 127 return(rc); 128 128 } 129 129 130 130 static int32_t unlock_parental(struct s_reader * reader) 131 131 { 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 132 /* disabling parental lock. assuming pin "0000" if no pin code is provided in the config */ 133 134 static const uchar inDPL[] = {0xca, 0x24, 0x02, 0x00, 0x09}; 135 uchar cmDPL[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F}; 136 def_resp; 137 138 if (strcmp(reader->pincode, "none")) { 139 cs_log("[viaccess-reader] Using PIN %s",reader->pincode); 140 // the pin need to be coded in bcd, so we need to convert from ascii to bcd, so '1234' -> 0x12 0x34 141 cmDPL[6]=((reader->pincode[0]-0x30)<<4) | ((reader->pincode[1]-0x30) & 0x0f); 142 cmDPL[7]=((reader->pincode[2]-0x30)<<4) | ((reader->pincode[3]-0x30) & 0x0f); 143 } 144 else { 145 cs_log("[viaccess-reader] Using PIN 0000!"); 146 } 147 write_cmd(inDPL,cmDPL); 148 if( !(cta_res[cta_lr-2]==0x90 && cta_res[cta_lr-1]==0) ) { 149 if (strcmp(reader->pincode, "none")) { 150 cs_log("[viaccess-reader] Can't disable parental lock. Wrong PIN? OSCam used %s!",reader->pincode); 151 } 152 else { 153 cs_log("[viaccess-reader] Can't disable parental lock. Wrong PIN? OSCam used 0000!"); 154 } 155 } 156 else 157 cs_log("[viaccess-reader] Parental lock disabled"); 158 159 return 0; 160 160 } 161 161 162 162 static int32_t viaccess_card_init(struct s_reader * reader, ATR newatr) 163 163 { 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 // switch((atr[atrsize-4]<<8)|atr[atrsize-3])201 // {202 // case 0x6268: ver="2.3"; break;203 // case 0x6668: ver="2.4(?)"; break;204 // case 0xa268:205 // default: ver="unknown"; break;206 // }207 208 209 210 211 212 213 // cs_log("[viaccess-reader] type: Viaccess, ver: %s serial: %llu", ver, b2ll(5, cta_res+2));214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 //cs_log("[viaccess-reader] buf: %s", buf);229 230 231 232 233 234 /*235 236 237 238 239 240 cs_log("[viaccess-reader] name: %s", cta_res);241 */242 243 244 245 246 247 248 249 250 251 252 253 254 164 get_atr; 165 def_resp; 166 int32_t i; 167 uchar buf[256]; 168 uchar insac[] = { 0xca, 0xac, 0x00, 0x00, 0x00 }; // select data 169 uchar insb8[] = { 0xca, 0xb8, 0x00, 0x00, 0x00 }; // read selected data 170 uchar insa4[] = { 0xca, 0xa4, 0x00, 0x00, 0x00 }; // select issuer 171 uchar insc0[] = { 0xca, 0xc0, 0x00, 0x00, 0x00 }; // read data item 172 static const uchar insFAC[] = { 0x87, 0x02, 0x00, 0x00, 0x03 }; // init FAC 173 static const uchar FacDat[] = { 0x00, 0x00, 0x28 }; 174 static unsigned char ins8702_data[] = { 0x00, 0x00, 0x11}; 175 static unsigned char ins8704[] = { 0x87, 0x04, 0x00, 0x00, 0x07 }; 176 static unsigned char ins8706[] = { 0x87, 0x06, 0x00, 0x00, 0x04 }; 177 178 179 if ((atr[1]!=0x77) || ((atr[2]!=0x18) && (atr[2]!=0x11) && (atr[2]!=0x19)) || (atr[9]!=0x68)) 180 return ERROR; 181 182 write_cmd(insFAC, FacDat); 183 if( !(cta_res[cta_lr-2]==0x90 && cta_res[cta_lr-1]==0) ) 184 return ERROR; 185 186 memset(&reader->last_geo, 0, sizeof(reader->last_geo)); 187 write_cmd(insFAC, ins8702_data); 188 if ((cta_res[cta_lr-2]==0x90) && (cta_res[cta_lr-1]==0x00)) { 189 write_cmd(ins8704, NULL); 190 if ((cta_res[cta_lr-2]==0x90) && (cta_res[cta_lr-1]==0x00)) { 191 write_cmd(ins8706, NULL); 192 if ((cta_res[cta_lr-2]==0x90) && (cta_res[cta_lr-1]==0x00)) { 193 reader->last_geo.number_ecm =(cta_res[2]<<8) | (cta_res[3]); 194 cs_log("[viaccess-reader] using ecm #%x for long viaccess ecm",reader->last_geo.number_ecm); 195 } 196 } 197 } 198 199 200 // switch((atr[atrsize-4]<<8)|atr[atrsize-3]) 201 // { 202 // case 0x6268: ver="2.3"; break; 203 // case 0x6668: ver="2.4(?)"; break; 204 // case 0xa268: 205 // default: ver="unknown"; break; 206 // } 207 208 reader->caid=0x500; 209 memset(reader->prid, 0xff, sizeof(reader->prid)); 210 insac[2]=0xa4; write_cmd(insac, NULL); // request unique id 211 insb8[4]=0x07; write_cmd(insb8, NULL); // read unique id 212 memcpy(reader->hexserial, cta_res+2, 5); 213 // cs_log("[viaccess-reader] type: Viaccess, ver: %s serial: %llu", ver, b2ll(5, cta_res+2)); 214 cs_ri_log(reader, "type: Viaccess (%sstandard atr), caid: %04X, serial: %llu", 215 atr[9]==0x68?"":"non-",reader->caid, b2ll(5, cta_res+2)); 216 217 i=0; 218 insa4[2]=0x00; write_cmd(insa4, NULL); // select issuer 0 219 buf[0]=0; 220 while((cta_res[cta_lr-2]==0x90) && (cta_res[cta_lr-1]==0)) 221 { 222 insc0[4]=0x1a; write_cmd(insc0, NULL); // show provider properties 223 cta_res[2]&=0xF0; 224 reader->prid[i][0]=0; 225 memcpy(&reader->prid[i][1], cta_res, 3); 226 memcpy(&reader->availkeys[i][0], cta_res+10, 16); 227 snprintf((char *)buf+strlen((char *)buf), sizeof(buf)-strlen((char *)buf), ",%06X", b2i(3, &reader->prid[i][1])); 228 //cs_log("[viaccess-reader] buf: %s", buf); 229 230 insac[2]=0xa5; write_cmd(insac, NULL); // request sa 231 insb8[4]=0x06; write_cmd(insb8, NULL); // read sa 232 memcpy(&reader->sa[i][0], cta_res+2, 4); 233 234 /* 235 insac[2]=0xa7; write_cmd(insac, NULL); // request name 236 insb8[4]=0x02; write_cmd(insb8, NULL); // read name nano + len 237 l=cta_res[1]; 238 insb8[4]=l; write_cmd(insb8, NULL); // read name 239 cta_res[l]=0; 240 cs_log("[viaccess-reader] name: %s", cta_res); 241 */ 242 243 insa4[2]=0x02; 244 write_cmd(insa4, NULL); // select next issuer 245 i++; 246 } 247 reader->nprov=i; 248 cs_ri_log(reader, "providers: %d (%s)", reader->nprov, buf+1); 249 250 if (cfg.ulparent) 251 unlock_parental(reader); 252 253 cs_log("[viaccess-reader] ready for requests"); 254 return OK; 255 255 } 256 256 257 257 bool check_crc( uchar *data ) 258 258 { 259 260 261 262 263 264 265 266 267 268 269 259 int32_t valid = 0; 260 261 uchar sum1=data[0] + data[1] + data[2] ; 262 uchar sum2=data[4] + data[5] + data[6] ; 263 uchar sum3=data[8] + data[9] + data[10] ; 264 uchar sum4=data[12] + data[13] + data[14] ; 265 266 if ( ( sum1 == data[3] ) && ( sum2 == data[7] ) && ( sum3 == data[11] )&& ( sum4 == data[15] ) ) 267 valid = 1; 268 269 return valid; 270 270 } 271 271 272 272 static int32_t viaccess_do_ecm(struct s_reader * reader, ECM_REQUEST *er) 273 273 { 274 def_resp; 275 static const unsigned char insa4[] = { 0xca,0xa4,0x04,0x00,0x03 }; // set provider id 276 unsigned char ins88[] = { 0xca,0x88,0x00,0x00,0x00 }; // set ecm 277 unsigned char insf8[] = { 0xca,0xf8,0x00,0x00,0x00 }; // set geographic info 278 static const unsigned char insc0[] = { 0xca,0xc0,0x00,0x00,0x12 }; // read dcw 279 280 uchar *ecm88Data=er->ecm+4; //XXX what is the 4th byte for ?? 281 int32_t ecm88Len=SCT_LEN(er->ecm)-4; 282 uint32_t provid=0; 283 int32_t rc=0; 284 int32_t hasD2 = 0; 285 int32_t curEcm88len=0; 286 int32_t nanoLen=0; 287 uchar *nextEcm; 288 uchar DE04[256]; 289 int32_t D2KeyID=0; 290 int32_t curnumber_ecm=0; 291 //nanoD2 d2 02 0d 02 -> D2 nano, len 2 292 // 0d -> post AES decrypt CW 293 // 0b -> pre AES decrypt CW 294 int32_t nanoD2 = 0; // 0x0b = 1 0x0d = 2 295 296 memset(DE04, 0, sizeof(DE04)); //fix dorcel de04 bug 297 298 nextEcm=ecm88Data; 299 300 while (ecm88Len && !rc) { 301 302 if(ecm88Data[0] ==0x00 && ecm88Data[1] == 0x00) { 303 // nano 0x00 and len 0x00 aren't valid ... something is obviously wrong with this ecm. 304 cs_log("[viaccess-reader] ECM: Invalid ECM structure. Rejecting"); 305 return ERROR; 306 } 307 308 // 80 33 nano 80 (ecm) + len (33) 309 if(ecm88Data[0]==0x80) { // nano 80, give ecm len 310 curEcm88len=ecm88Data[1]; 311 nextEcm=ecm88Data+curEcm88len+2; 312 ecm88Data += 2; 313 ecm88Len -= 2; 314 } 315 316 if(!curEcm88len) { //there was no nano 80 -> simple ecm 317 curEcm88len=ecm88Len; 318 } 319 320 // d2 02 0d 02 -> D2 nano, len 2, select the AES key to be used 321 if(ecm88Data[0]==0xd2) { 322 // test if need post or pre AES decrypt 323 if(ecm88Data[2]==0x0b) 324 { 325 nanoD2 = 1; 326 cs_debug_mask(D_READER, "[viaccess-reader] ECM: nano D2 0x0b"); 327 } 328 if(ecm88Data[2]==0x0d) 329 { 330 nanoD2 = 2; 331 cs_debug_mask(D_READER, "[viaccess-reader] ECM: nano D2 0x0d"); 332 } 333 // use the d2 arguments to get the key # to be used 334 int32_t len = ecm88Data[1] + 2; 335 D2KeyID=ecm88Data[3]; 336 ecm88Data += len; 337 ecm88Len -= len; 338 curEcm88len -=len; 339 hasD2 = 1; 340 } 341 else 342 hasD2 = 0; 343 344 345 // 40 07 03 0b 00 -> nano 40, len =7 ident 030B00 (tntsat), key #0 <== we're pointing here 346 // 09 -> use key #9 347 // 05 67 00 348 if ((ecm88Data[0]==0x90 || ecm88Data[0]==0x40) && (ecm88Data[1]==0x03 || ecm88Data[1]==0x07 ) ) 349 { 350 uchar ident[3], keynr; 351 uchar *ecmf8Data=0; 352 int32_t ecmf8Len=0; 353 354 nanoLen=ecm88Data[1] + 2; 355 keynr=ecm88Data[4]&0x0F; 356 357 // 40 07 03 0b 00 -> nano 40, len =7 ident 030B00 (tntsat), key #0 <== we're pointing here 358 // 09 -> use key #9 359 if(nanoLen>5) { 360 curnumber_ecm =(ecm88Data[6]<<8) | (ecm88Data[7]); 361 cs_debug_mask(D_READER, "checking if the ecm number (%x) match the card one (%x)",curnumber_ecm,reader->last_geo.number_ecm); 362 // if we have an ecm number we check it. 363 // we can't assume that if the nano len is 5 or more we have an ecm number 364 // as some card don't support this 365 if( reader->last_geo.number_ecm > 0 ) { 366 if (reader->last_geo.number_ecm == curnumber_ecm && 367 !( ecm88Data[nanoLen-1] == 0x01 && (ecm88Data[2] == 0x03 && ecm88Data[3] == 0x0B && ecm88Data[4] == 0x00 ) )) { 368 keynr=ecm88Data[5]; 369 cs_debug_mask(D_READER, "keyToUse = %02x, ECM ending with %02x",ecm88Data[5], ecm88Data[nanoLen-1]); 370 } else { 371 if( ecm88Data[nanoLen-1] == 0x01 && (ecm88Data[2] == 0x03 && ecm88Data[3] == 0x0B && ecm88Data[4] == 0x00 ) ) 372 { 373 cs_debug_mask(D_READER, "Skip ECM ending with = %02x for ecm number (%x) for provider %02x%02x%02x",ecm88Data[nanoLen-1], curnumber_ecm, ecm88Data[2], ecm88Data[3], ecm88Data[4]); 374 } 375 cs_debug_mask(D_READER, "Skip ECM ending with = %02x for ecm number (%x)",ecm88Data[nanoLen-1], curnumber_ecm); 376 ecm88Data=nextEcm; 377 ecm88Len-=curEcm88len; 378 continue; //loop to next ecm 379 } 380 } 381 else { // long ecm but we don't have an ecm number so we have to try them all. 382 keynr=ecm88Data[5]; 383 cs_debug_mask(D_READER, "keyToUse = %02x",ecm88Data[5]); 384 } 385 } 386 387 memcpy (ident, &ecm88Data[2], sizeof(ident)); 388 provid = b2i(3, ident); 389 ident[2]&=0xF0; 390 391 if(hasD2 && reader->aes_list) { 392 // check that we have the AES key to decode the CW 393 // if not there is no need to send the ecm to the card 394 if(!aes_present(reader->aes_list, 0x500, (uint32_t) (provid & 0xFFFFF0) , D2KeyID)) 395 return ERROR; 396 } 397 398 399 if (!chk_prov(reader, ident, keynr)) 400 { 401 cs_debug_mask(D_READER, "[viaccess-reader] ECM: provider or key not found on card"); 402 snprintf( er->msglog, MSGLOGSIZE, "provider(%02x%02x%02x) or key(%d) not found on card", ident[0],ident[1],ident[2], keynr ); 403 return ERROR; 404 } 405 406 ecm88Data+=nanoLen; 407 ecm88Len-=nanoLen; 408 curEcm88len-=nanoLen; 409 410 // DE04 411 if (ecm88Data[0]==0xDE && ecm88Data[1]==0x04) 412 { 413 memcpy (DE04, &ecm88Data[0], 6); 414 ecm88Data+=6; 415 } 416 // 417 418 if( reader->last_geo.provid != provid ) 419 { 420 reader->last_geo.provid = provid; 421 reader->last_geo.geo_len = 0; 422 reader->last_geo.geo[0] = 0; 423 write_cmd(insa4, ident); // set provider 424 } 425 426 //Nano D2 0x0b Pre AES decrypt CW 427 if ( hasD2 && nanoD2 == 1) 428 { 429 uchar *ecm88DataCW = ecm88Data; 430 int32_t cwStart = 0; 431 //int32_t cwStartRes = 0; 432 int32_t exit = 0; 433 // find CW start 434 while(cwStart < curEcm88len -1 && !exit) 435 { 436 if(ecm88Data[cwStart] == 0xEA && ecm88Data[cwStart+1] == 0x10) 437 { 438 ecm88DataCW = ecm88DataCW + cwStart + 2; 439 exit = 1; 440 } 441 cwStart++; 442 } 443 // use AES from list to decrypt CW 444 cs_debug_mask(D_READER, "Decoding CW : using AES key id %d for provider %06x",D2KeyID, (provid & 0xFFFFF0)); 445 if (aes_decrypt_from_list(reader->aes_list,0x500, (uint32_t) (provid & 0xFFFFF0), D2KeyID, &ecm88DataCW[0], 16) == 0) 446 snprintf( er->msglog, MSGLOGSIZE, "AES Decrypt : key id %d not found for CAID %04X , provider %06x", D2KeyID, 0x500, (provid & 0xFFFFF0) ); 447 } 448 449 while(ecm88Len>0 && ecm88Data[0]<0xA0) 450 { 451 int32_t nanoLen=ecm88Data[1]+2; 452 if (!ecmf8Data) 453 ecmf8Data=(uchar *)ecm88Data; 454 ecmf8Len+=nanoLen; 455 ecm88Len-=nanoLen; 456 curEcm88len-=nanoLen; 457 ecm88Data+=nanoLen; 458 } 459 if(ecmf8Len) 460 { 461 if( reader->last_geo.geo_len!=ecmf8Len || 462 memcmp(reader->last_geo.geo, ecmf8Data, reader->last_geo.geo_len)) 463 { 464 memcpy(reader->last_geo.geo, ecmf8Data, ecmf8Len); 465 reader->last_geo.geo_len= ecmf8Len; 466 insf8[3]=keynr; 467 insf8[4]=ecmf8Len; 468 write_cmd(insf8, ecmf8Data); 469 } 470 } 471 ins88[2]=ecmf8Len?1:0; 472 ins88[3]=keynr; 473 ins88[4]= curEcm88len; 474 // 475 // we should check the nano to make sure the ecm is valid 476 // we should look for at least 1 E3 nano, 1 EA nano and the F0 signature nano 477 // 478 // DE04 479 if (DE04[0]==0xDE) 480 { 481 memcpy(DE04+6, (uchar *)ecm88Data, curEcm88len-6); 482 write_cmd(ins88, DE04); // request dcw 483 } 484 else 485 { 486 write_cmd(ins88, (uchar *)ecm88Data); // request dcw 487 } 488 // 489 write_cmd(insc0, NULL); // read dcw 490 switch(cta_res[0]) 491 { 492 case 0xe8: // even 493 if(cta_res[1]==8) { memcpy(er->cw,cta_res+2,8); rc=1; } 494 break; 495 case 0xe9: // odd 496 if(cta_res[1]==8) { memcpy(er->cw+8,cta_res+2,8); rc=1; } 497 break; 498 case 0xea: // complete 499 if(cta_res[1]==16) { memcpy(er->cw,cta_res+2,16); rc=1; } 500 break; 501 default : 502 ecm88Data=nextEcm; 503 ecm88Len-=curEcm88len; 504 cs_debug_mask(D_READER, "[viaccess-reader] ECM: key to use is not the current one, trying next ECM"); 505 snprintf( er->msglog, MSGLOGSIZE, "key to use is not the current one, trying next ECM" ); 506 } 507 } 508 else { 509 ecm88Data=nextEcm; 510 ecm88Len-=curEcm88len; 511 cs_debug_mask(D_READER, "[viaccess-reader] ECM: Unknown ECM type"); 512 snprintf( er->msglog, MSGLOGSIZE, "Unknown ECM type" ); 513 } 514 } 515 516 if ( hasD2 && !check_crc(er->cw) && nanoD2 == 2) { 517 cs_debug_mask(D_READER, "Decoding CW : using AES key id %d for provider %06x",D2KeyID, (provid & 0xFFFFF0)); 518 rc=aes_decrypt_from_list(reader->aes_list,0x500, (uint32_t) (provid & 0xFFFFF0), D2KeyID,er->cw, 16); 519 if( rc == 0 ) 520 snprintf( er->msglog, MSGLOGSIZE, "AES Decrypt : key id %d not found for CAID %04X , provider %06x", D2KeyID, 0x500, (provid & 0xFFFFF0) ); 521 } 522 523 return(rc?OK:ERROR); 274 def_resp; 275 static const unsigned char insa4[] = { 0xca,0xa4,0x04,0x00,0x03 }; // set provider id 276 unsigned char ins88[] = { 0xca,0x88,0x00,0x00,0x00 }; // set ecm 277 unsigned char insf8[] = { 0xca,0xf8,0x00,0x00,0x00 }; // set geographic info 278 static const unsigned char insc0[] = { 0xca,0xc0,0x00,0x00,0x12 }; // read dcw 279 280 uchar *ecm88Data=er->ecm+4; //XXX what is the 4th byte for ?? 281 int32_t ecm88Len=SCT_LEN(er->ecm)-4; 282 uint32_t provid=0; 283 int32_t rc=0; 284 int32_t hasD2 = 0; 285 int32_t curEcm88len=0; 286 int32_t nanoLen=0; 287 uchar *nextEcm; 288 uchar DE04[256]; 289 int32_t D2KeyID=0; 290 int32_t curnumber_ecm=0; 291 //nanoD2 d2 02 0d 02 -> D2 nano, len 2 292 // 0d -> post AES decrypt CW 293 // 0b -> pre AES decrypt CW 294 int32_t nanoD2 = 0; // 0x0b = 1 0x0d = 2 295 296 memset(DE04, 0, sizeof(DE04)); //fix dorcel de04 bug 297 298 nextEcm=ecm88Data; 299 300 while (ecm88Len && !rc) { 301 302 if(ecm88Data[0] ==0x00 && ecm88Data[1] == 0x00) { 303 // nano 0x00 and len 0x00 aren't valid ... something is obviously wrong with this ecm. 304 cs_log("[viaccess-reader] ECM: Invalid ECM structure. Rejecting"); 305 return ERROR; 306 } 307 308 // 80 33 nano 80 (ecm) + len (33) 309 if(ecm88Data[0]==0x80) { // nano 80, give ecm len 310 curEcm88len=ecm88Data[1]; 311 nextEcm=ecm88Data+curEcm88len+2; 312 ecm88Data += 2; 313 ecm88Len -= 2; 314 } 315 316 if(!curEcm88len) { //there was no nano 80 -> simple ecm 317 curEcm88len=ecm88Len; 318 } 319 320 // d2 02 0d 02 -> D2 nano, len 2, select the AES key to be used 321 if(ecm88Data[0]==0xd2) { 322 // test if need post or pre AES decrypt 323 if(ecm88Data[2]==0x0b) 324 { 325 nanoD2 = 1; 326 cs_debug_mask(D_READER, "[viaccess-reader] ECM: nano D2 0x0b"); 327 } 328 if(ecm88Data[2]==0x0d) 329 { 330 nanoD2 = 2; 331 cs_debug_mask(D_READER, "[viaccess-reader] ECM: nano D2 0x0d"); 332 } 333 // use the d2 arguments to get the key # to be used 334 int32_t len = ecm88Data[1] + 2; 335 D2KeyID=ecm88Data[3]; 336 ecm88Data += len; 337 ecm88Len -= len; 338 curEcm88len -=len; 339 hasD2 = 1; 340 } 341 else 342 hasD2 = 0; 343 344 345 // 40 07 03 0b 00 -> nano 40, len =7 ident 030B00 (tntsat), key #0 <== we're pointing here 346 // 09 -> use key #9 347 // 05 67 00 348 if ((ecm88Data[0]==0x90 || ecm88Data[0]==0x40) && (ecm88Data[1]==0x03 || ecm88Data[1]==0x07 ) ) 349 { 350 uchar ident[3], keynr; 351 uchar *ecmf8Data=0; 352 int32_t ecmf8Len=0; 353 354 nanoLen=ecm88Data[1] + 2; 355 keynr=ecm88Data[4]&0x0F; 356 357 // 40 07 03 0b 00 -> nano 40, len =7 ident 030B00 (tntsat), key #0 <== we're pointing here 358 // 09 -> use key #9 359 if(nanoLen>5) { 360 curnumber_ecm =(ecm88Data[6]<<8) | (ecm88Data[7]); 361 cs_debug_mask(D_READER, "checking if the ecm number (%x) match the card one (%x)",curnumber_ecm,reader->last_geo.number_ecm); 362 // if we have an ecm number we check it. 363 // we can't assume that if the nano len is 5 or more we have an ecm number 364 // as some card don't support this 365 //force use ecm 00 provider 030B00 & 032940 366 if( reader->last_geo.number_ecm > 0 ) 367 { 368 if(ecm88Data[2] == 0x03 && ((ecm88Data[3] == 0x0B && ecm88Data[4] == 0x00)|| 369 (ecm88Data[3] == 0x29 && ecm88Data[4] == 0x40))) 370 { 371 if (reader->last_geo.number_ecm == curnumber_ecm && !( ecm88Data[nanoLen-1] == 0x01 )) //ecm 00 372 { 373 keynr=ecm88Data[5]; 374 cs_debug_mask(D_READER, "keyToUse = %02x, ECM ending with %02x",ecm88Data[5], ecm88Data[nanoLen-1]); 375 } 376 else 377 { 378 // ecm 01 379 if( ecm88Data[nanoLen-1] == 0x01 ) 380 { 381 cs_debug_mask(D_READER, "Skip ECM ending with = %02x for ecm number (%x) for provider %02x%02x%02x",ecm88Data[nanoLen-1], curnumber_ecm, ecm88Data[2], ecm88Data[3], ecm88Data[4]); 382 } 383 cs_debug_mask(D_READER, "Skip ECM ending with = %02x for ecm number (%x)",ecm88Data[nanoLen-1], curnumber_ecm); 384 ecm88Data=nextEcm; 385 ecm88Len-=curEcm88len; 386 continue; //loop to next ecm 387 } 388 } 389 } 390 else { // long ecm but we don't have an ecm number so we have to try them all. 391 keynr=ecm88Data[5]; 392 cs_debug_mask(D_READER, "keyToUse = %02x",ecm88Data[5]); 393 } 394 } 395 396 memcpy (ident, &ecm88Data[2], sizeof(ident)); 397 provid = b2i(3, ident); 398 ident[2]&=0xF0; 399 400 if(hasD2 && reader->aes_list) { 401 // check that we have the AES key to decode the CW 402 // if not there is no need to send the ecm to the card 403 if(!aes_present(reader->aes_list, 0x500, (uint32_t) (provid & 0xFFFFF0) , D2KeyID)) 404 return ERROR; 405 } 406 407 408 if (!chk_prov(reader, ident, keynr)) 409 { 410 cs_debug_mask(D_READER, "[viaccess-reader] ECM: provider or key not found on card"); 411 snprintf( er->msglog, MSGLOGSIZE, "provider(%02x%02x%02x) or key(%d) not found on card", ident[0],ident[1],ident[2], keynr ); 412 return ERROR; 413 } 414 415 ecm88Data+=nanoLen; 416 ecm88Len-=nanoLen; 417 curEcm88len-=nanoLen; 418 419 // DE04 420 if (ecm88Data[0]==0xDE && ecm88Data[1]==0x04) 421 { 422 memcpy (DE04, &ecm88Data[0], 6); 423 ecm88Data+=6; 424 } 425 // 426 427 if( reader->last_geo.provid != provid ) 428 { 429 reader->last_geo.provid = provid; 430 reader->last_geo.geo_len = 0; 431 reader->last_geo.geo[0] = 0; 432 write_cmd(insa4, ident); // set provider 433 } 434 435 //Nano D2 0x0b Pre AES decrypt CW 436 if ( hasD2 && nanoD2 == 1) 437 { 438 uchar *ecm88DataCW = ecm88Data; 439 int32_t cwStart = 0; 440 //int32_t cwStartRes = 0; 441 int32_t exit = 0; 442 // find CW start 443 while(cwStart < curEcm88len -1 && !exit) 444 { 445 if(ecm88Data[cwStart] == 0xEA && ecm88Data[cwStart+1] == 0x10) 446 { 447 ecm88DataCW = ecm88DataCW + cwStart + 2; 448 exit = 1; 449 } 450 cwStart++; 451 } 452 // use AES from list to decrypt CW 453 cs_debug_mask(D_READER, "Decoding CW : using AES key id %d for provider %06x",D2KeyID, (provid & 0xFFFFF0)); 454 if (aes_decrypt_from_list(reader->aes_list,0x500, (uint32_t) (provid & 0xFFFFF0), D2KeyID, &ecm88DataCW[0], 16) == 0) 455 snprintf( er->msglog, MSGLOGSIZE, "AES Decrypt : key id %d not found for CAID %04X , provider %06x", D2KeyID, 0x500, (provid & 0xFFFFF0) ); 456 } 457 458 while(ecm88Len>0 && ecm88Data[0]<0xA0) 459 { 460 int32_t nanoLen=ecm88Data[1]+2; 461 if (!ecmf8Data) 462 ecmf8Data=(uchar *)ecm88Data; 463 ecmf8Len+=nanoLen; 464 ecm88Len-=nanoLen; 465 curEcm88len-=nanoLen; 466 ecm88Data+=nanoLen; 467 } 468 if(ecmf8Len) 469 { 470 if( reader->last_geo.geo_len!=ecmf8Len || 471 memcmp(reader->last_geo.geo, ecmf8Data, reader->last_geo.geo_len)) 472 { 473 memcpy(reader->last_geo.geo, ecmf8Data, ecmf8Len); 474 reader->last_geo.geo_len= ecmf8Len; 475 insf8[3]=keynr; 476 insf8[4]=ecmf8Len; 477 write_cmd(insf8, ecmf8Data); 478 } 479 } 480 ins88[2]=ecmf8Len?1:0; 481 ins88[3]=keynr; 482 ins88[4]= curEcm88len; 483 // 484 // we should check the nano to make sure the ecm is valid 485 // we should look for at least 1 E3 nano, 1 EA nano and the F0 signature nano 486 // 487 // DE04 488 if (DE04[0]==0xDE) 489 { 490 memcpy(DE04+6, (uchar *)ecm88Data, curEcm88len-6); 491 write_cmd(ins88, DE04); // request dcw 492 } 493 else 494 { 495 write_cmd(ins88, (uchar *)ecm88Data); // request dcw 496 } 497 // 498 write_cmd(insc0, NULL); // read dcw 499 switch(cta_res[0]) 500 { 501 case 0xe8: // even 502 if(cta_res[1]==8) { memcpy(er->cw,cta_res+2,8); rc=1; } 503 break; 504 case 0xe9: // odd 505 if(cta_res[1]==8) { memcpy(er->cw+8,cta_res+2,8); rc=1; } 506 break; 507 case 0xea: // complete 508 if(cta_res[1]==16) { memcpy(er->cw,cta_res+2,16); rc=1; } 509 break; 510 default : 511 ecm88Data=nextEcm; 512 ecm88Len-=curEcm88len; 513 cs_debug_mask(D_READER, "[viaccess-reader] ECM: key to use is not the current one, trying next ECM"); 514 snprintf( er->msglog, MSGLOGSIZE, "key to use is not the current one, trying next ECM" ); 515 } 516 } 517 else { 518 ecm88Data=nextEcm; 519 ecm88Len-=curEcm88len; 520 cs_debug_mask(D_READER, "[viaccess-reader] ECM: Unknown ECM type"); 521 snprintf( er->msglog, MSGLOGSIZE, "Unknown ECM type" ); 522 } 523 } 524 525 if ( hasD2 && !check_crc(er->cw) && nanoD2 == 2) { 526 cs_debug_mask(D_READER, "Decoding CW : using AES key id %d for provider %06x",D2KeyID, (provid & 0xFFFFF0)); 527 rc=aes_decrypt_from_list(reader->aes_list,0x500, (uint32_t) (provid & 0xFFFFF0), D2KeyID,er->cw, 16); 528 if( rc == 0 ) 529 snprintf( er->msglog, MSGLOGSIZE, "AES Decrypt : key id %d not found for CAID %04X , provider %06x", D2KeyID, 0x500, (provid & 0xFFFFF0) ); 530 } 531 532 return(rc?OK:ERROR); 524 533 } 525 534 … … 535 544 536 545 switch (ep->emm[0]) { 537 case 0x88: 538 ep->type=UNIQUE; 539 memset(ep->hexserial, 0, 8); 540 memcpy(ep->hexserial, ep->emm + 4, 4); 541 cs_debug_mask(D_EMM, "VIACCESS EMM: UNIQUE"); 542 return(!memcmp(rdr->hexserial + 1, ep->hexserial, 4)); 543 544 case 0x8A: 545 case 0x8B: 546 ep->type=GLOBAL; 547 cs_debug_mask(D_EMM, "VIACCESS EMM: GLOBAL"); 546 case 0x88: 547 ep->type=UNIQUE; 548 memset(ep->hexserial, 0, 8); 549 memcpy(ep->hexserial, ep->emm + 4, 4); 550 cs_debug_mask(D_EMM, "VIACCESS EMM: UNIQUE"); 551 return(!memcmp(rdr->hexserial + 1, ep->hexserial, 4)); 552 553 case 0x8A: 554 case 0x8B: 555 ep->type=GLOBAL; 556 cs_debug_mask(D_EMM, "VIACCESS EMM: GLOBAL"); 557 return TRUE; 558 559 case 0x8C: 560 case 0x8D: 561 ep->type=SHARED; 562 cs_debug_mask(D_EMM, "VIACCESS EMM: SHARED (part)"); 563 return FALSE; 564 565 case 0x8E: 566 ep->type=SHARED; 567 memset(ep->hexserial, 0, 8); 568 memcpy(ep->hexserial, ep->emm + 3, 3); 569 cs_debug_mask(D_EMM, "VIACCESS EMM: SHARED"); 570 571 //check for provider as serial (cccam only?) 572 int8_t i; 573 for (i=0;i<rdr->nprov;i++) { 574 if (!memcmp(&rdr->prid[i][1], ep->hexserial, 3)) 548 575 return TRUE; 549 550 case 0x8C: 551 case 0x8D: 552 ep->type=SHARED; 553 cs_debug_mask(D_EMM, "VIACCESS EMM: SHARED (part)"); 554 return FALSE; 555 556 case 0x8E: 557 ep->type=SHARED; 558 memset(ep->hexserial, 0, 8); 559 memcpy(ep->hexserial, ep->emm + 3, 3); 560 cs_debug_mask(D_EMM, "VIACCESS EMM: SHARED"); 561 562 //check for provider as serial (cccam only?) 563 int8_t i; 564 for (i=0;i<rdr->nprov;i++) { 565 if (!memcmp(&rdr->prid[i][1], ep->hexserial, 3)) 566 return TRUE; 567 } 568 return(!memcmp(&rdr->sa[0][0], ep->hexserial, 3)); 569 570 default: 571 ep->type = UNKNOWN; 572 cs_debug_mask(D_EMM, "VIACCESS EMM: UNKNOWN"); 573 return TRUE; 576 } 577 return(!memcmp(&rdr->sa[0][0], ep->hexserial, 3)); 578 579 default: 580 ep->type = UNKNOWN; 581 cs_debug_mask(D_EMM, "VIACCESS EMM: UNKNOWN"); 582 return TRUE; 574 583 } 575 584 } … … 614 623 static int32_t viaccess_do_emm(struct s_reader * reader, EMM_PACKET *ep) 615 624 { 616 617 618 619 620 621 622 623 625 def_resp; 626 static const unsigned char insa4[] = { 0xca,0xa4,0x04,0x00,0x03 }; // set provider id 627 unsigned char insf0[] = { 0xca,0xf0,0x00,0x01,0x22 }; // set adf 628 unsigned char insf4[] = { 0xca,0xf4,0x00,0x01,0x00 }; // set adf, encrypted 629 unsigned char ins18[] = { 0xca,0x18,0x01,0x01,0x00 }; // set subscription 630 unsigned char ins1c[] = { 0xca,0x1c,0x01,0x01,0x00 }; // set subscription, encrypted 631 static const unsigned char insc8[] = { 0xca,0xc8,0x00,0x00,0x02 }; // read extended status 632 // static const unsigned char insc8Data[] = { 0x00,0x00 }; // data for read extended status 624 633 625 634 int32_t emmdatastart=7; … … 639 648 } 640 649 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 */850 650 if (ep->type == UNIQUE) emmdatastart++; 651 int32_t emmLen=SCT_LEN(ep->emm)-emmdatastart; 652 int32_t rc=0; 653 654 ///cs_dump(ep->emm, emmLen+emmdatastart, "RECEIVED EMM VIACCESS"); 655 656 int32_t emmUpToEnd; 657 uchar *emmParsed = ep->emm+emmdatastart; 658 int32_t provider_ok = 0; 659 uint32_t emm_provid; 660 uchar keynr = 0; 661 int32_t ins18Len = 0; 662 uchar ins18Data[512]; 663 uchar insData[512]; 664 uchar *nano81Data = 0; 665 uchar *nano91Data = 0; 666 uchar *nano92Data = 0; 667 uchar *nano9EData = 0; 668 uchar *nanoF0Data = 0; 669 670 for (emmUpToEnd=emmLen; (emmParsed[1] != 0) && (emmUpToEnd > 0); emmUpToEnd -= (2 + emmParsed[1]), emmParsed += (2 + emmParsed[1])) { 671 ///cs_dump (emmParsed, emmParsed[1] + 2, "NANO"); 672 673 if (emmParsed[0]==0x90 && emmParsed[1]==0x03) { 674 /* identification of the service operator */ 675 676 uchar soid[3], ident[3], i; 677 678 for (i=0; i<3; i++) { 679 soid[i]=ident[i]=emmParsed[2+i]; 680 } 681 ident[2]&=0xF0; 682 emm_provid=b2i(3, ident); 683 keynr=soid[2]&0x0F; 684 if (chk_prov(reader, ident, keynr)) { 685 provider_ok = 1; 686 } else { 687 cs_debug_mask(D_READER, "[viaccess-reader] EMM: provider or key not found on card (%x, %x)", ident, keynr); 688 cs_log("[viaccess-reader] EMM: provider or key not found on card (%x, %x)", ident, keynr); 689 return ERROR; 690 } 691 692 // check if the provider changes. If yes, set the new one. If not, don't .. card will return an error if we do. 693 if( reader->last_geo.provid != emm_provid ) { 694 write_cmd(insa4, ident); 695 if( cta_res[cta_lr-2]!=0x90 || cta_res[cta_lr-1]!=0x00 ) { 696 cs_dump(insa4, 5, "set provider cmd:"); 697 cs_dump(soid, 3, "set provider data:"); 698 cs_log("[viaccess-reader] update error: %02X %02X", cta_res[cta_lr-2], cta_res[cta_lr-1]); 699 return ERROR; 700 } 701 } 702 // as we are maybe changing the used provider, clear the cache, so the next ecm will re-select the correct one 703 reader->last_geo.provid = 0; 704 reader->last_geo.geo_len = 0; 705 reader->last_geo.geo[0] = 0; 706 707 } 708 else if (emmParsed[0]==0x9e && emmParsed[1]==0x20) { 709 /* adf */ 710 711 if (!nano91Data) { 712 /* adf is not crypted, so test it */ 713 714 uchar custwp; 715 uchar *afd; 716 717 custwp=reader->sa[0][3]; 718 afd=(uchar*)emmParsed+2; 719 720 if( afd[31-custwp/8] & (1 << (custwp & 7)) ) 721 cs_debug_mask(D_READER, "[viaccess-reader] emm for our card %08X", b2i(4, &reader->sa[0][0])); 722 else 723 return SKIPPED; 724 } 725 726 // memorize 727 nano9EData = emmParsed; 728 729 } else if (emmParsed[0]==0x81) { 730 nano81Data = emmParsed; 731 } else if (emmParsed[0]==0x91 && emmParsed[1]==0x08) { 732 nano91Data = emmParsed; 733 } else if (emmParsed[0]==0x92 && emmParsed[1]==0x08) { 734 nano92Data = emmParsed; 735 } else if (emmParsed[0]==0xF0 && emmParsed[1]==0x08) { 736 nanoF0Data = emmParsed; 737 } else { 738 /* other nanos */ 739 show_subs(reader, emmParsed); 740 741 memcpy(ins18Data+ins18Len, emmParsed, emmParsed[1] + 2); 742 ins18Len += emmParsed [1] + 2; 743 } 744 } 745 746 if (!provider_ok) { 747 cs_debug_mask(D_READER, "[viaccess-reader] provider not found in emm, continue anyway"); 748 // force key to 1... 749 keynr = 1; 750 ///return ERROR; 751 } 752 753 if (!nanoF0Data) { 754 cs_dump(ep->emm, ep->l, "can't find 0xf0 in emm..."); 755 return ERROR; // error 756 } 757 758 if (nano9EData) { 759 if (!nano91Data) { 760 // set adf 761 insf0[3] = keynr; // key 762 insf0[4] = nano9EData[1] + 2; 763 write_cmd(insf0, nano9EData); 764 if( cta_res[cta_lr-2]!=0x90 || cta_res[cta_lr-1]!=0x00 ) { 765 cs_dump(insf0, 5, "set adf cmd:"); 766 cs_dump(nano9EData, insf0[4] , "set adf data:"); 767 cs_log("[viaccess-reader] update error: %02X %02X", cta_res[cta_lr-2], cta_res[cta_lr-1]); 768 return ERROR; 769 } 770 } else { 771 // set adf crypte 772 insf4[3] = keynr; // key 773 insf4[4] = nano91Data[1] + 2 + nano9EData[1] + 2; 774 memcpy (insData, nano91Data, nano91Data[1] + 2); 775 memcpy (insData + nano91Data[1] + 2, nano9EData, nano9EData[1] + 2); 776 write_cmd(insf4, insData); 777 if(( cta_res[cta_lr-2]!=0x90 && cta_res[cta_lr-2]!=0x91) || cta_res[cta_lr-1]!=0x00 ) { 778 cs_dump(insf4, 5, "set adf encrypted cmd:"); 779 cs_dump(insData, insf4[4], "set adf encrypted data:"); 780 cs_log("[viaccess-reader] update error: %02X %02X", cta_res[cta_lr-2], cta_res[cta_lr-1]); 781 return ERROR; 782 } 783 } 784 } 785 786 if (!nano92Data) { 787 // send subscription 788 ins18[2] = nano9EData ? 0x01: 0x00; // found 9E nano ? 789 ins18[3] = keynr; // key 790 ins18[4] = ins18Len + nanoF0Data[1] + 2; 791 memcpy (insData, ins18Data, ins18Len); 792 memcpy (insData + ins18Len, nanoF0Data, nanoF0Data[1] + 2); 793 write_cmd(ins18, insData); 794 if( (cta_res[cta_lr-2]==0x90 || cta_res[cta_lr-2]==0x91) && cta_res[cta_lr-1]==0x00 ) { 795 cs_debug_mask(D_READER, "[viaccess-reader] update successfully written"); 796 rc=1; // written 797 } else { 798 cs_dump(ins18, 5, "set subscription cmd:"); 799 cs_dump(insData, ins18[4], "set subscription data:"); 800 cs_log("[viaccess-reader] update error: %02X %02X", cta_res[cta_lr-2], cta_res[cta_lr-1]); 801 } 802 803 } else { 804 // send subscription encrypted 805 806 if (!nano81Data) { 807 cs_dump(ep->emm, ep->l, "0x92 found, but can't find 0x81 in emm..."); 808 return ERROR; // error 809 } 810 811 ins1c[2] = nano9EData ? 0x01: 0x00; // found 9E nano ? 812 if (ep->type == UNIQUE) ins1c[2] = 0x02; 813 ins1c[3] = keynr; // key 814 ins1c[4] = nano92Data[1] + 2 + nano81Data[1] + 2 + nanoF0Data[1] + 2; 815 memcpy (insData, nano92Data, nano92Data[1] + 2); 816 memcpy (insData + nano92Data[1] + 2, nano81Data, nano81Data[1] + 2); 817 memcpy (insData + nano92Data[1] + 2 + nano81Data[1] + 2, nanoF0Data, nanoF0Data[1] + 2); 818 write_cmd(ins1c, insData); 819 820 if( (cta_res[cta_lr-2]==0x90 && cta_res[cta_lr-1]==0x00) ) { 821 cs_log("[viaccess-reader] update successfully written"); 822 rc=1; // written 823 } 824 else { 825 if( cta_res[cta_lr-2]&0x1 ) 826 cs_log("[viaccess-reader] update not written. Data already exists or unknown address"); 827 828 //if( cta_res[cta_lr-2]&0x8 ) { 829 write_cmd(insc8, NULL); 830 if( (cta_res[cta_lr-2]==0x90 && cta_res[cta_lr-1]==0x00) ) { 831 cs_log("[viaccess-reader] extended status %02X %02X", cta_res[0], cta_res[1]); 832 } 833 //} 834 return ERROR; 835 } 836 837 } 838 839 /* 840 Sub Main() 841 Sc.Write("CA A4 04 00 03") 842 RX 843 Sc.Write("02 07 11") 844 RX 845 Sc.Write("CA F0 00 01 22") 846 RX 847 Sc.Write("9E 20") 848 Sc.Write("10 10 08 8A 80 00 04 00 10 10 26 E8 54 80 1E 80") 849 Sc.Write("00 01 00 00 00 00 00 50 00 00 80 02 22 00 08 50") 850 RX 851 Sc.Write("CA 18 01 01 11") 852 RX 853 Sc.Write("A9 05 34 DE 34 FF 80") 854 Sc.Write("F0 08 1A 3E AF B5 2B EE E3 3B") 855 RX 856 857 End Sub 858 */ 859 return rc; 851 860 } 852 861 853 862 static int32_t viaccess_card_info(struct s_reader * reader) 854 863 { 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 864 def_resp; 865 int32_t i, l, scls, show_cls; 866 uchar insac[] = { 0xca, 0xac, 0x00, 0x00, 0x00 }; // select data 867 uchar insb8[] = { 0xca, 0xb8, 0x00, 0x00, 0x00 }; // read selected data 868 uchar insa4[] = { 0xca, 0xa4, 0x00, 0x00, 0x00 }; // select issuer 869 uchar insc0[] = { 0xca, 0xc0, 0x00, 0x00, 0x00 }; // read data item 870 static const uchar ins24[] = { 0xca, 0x24, 0x00, 0x00, 0x09 }; // set pin 871 872 static const uchar cls[] = { 0x00, 0x21, 0xff, 0x9f}; 873 static const uchar pin[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04}; 874 875 show_cls=reader->show_cls; 876 reader->last_geo.provid = 0; 877 reader->last_geo.geo_len = 0; 878 reader->last_geo.geo[0] = 0; 879 880 cs_log("[viaccess-reader] card detected"); 881 882 // set pin 883 write_cmd(ins24, pin); 884 885 insac[2]=0xa4; write_cmd(insac, NULL); // request unique id 886 insb8[4]=0x07; write_cmd(insb8, NULL); // read unique id 887 cs_log("[viaccess-reader] serial: %llu", b2ll(5, cta_res+2)); 888 889 scls=0; 890 insa4[2]=0x00; write_cmd(insa4, NULL); // select issuer 0 891 for (i=1; (cta_res[cta_lr-2]==0x90) && (cta_res[cta_lr-1]==0); i++) 892 { 893 uint32_t l_provid, l_sa; 894 uchar l_name[64]; 895 insc0[4]=0x1a; write_cmd(insc0, NULL); // show provider properties 896 cta_res[2]&=0xF0; 897 l_provid=b2i(3, cta_res); 898 899 insac[2]=0xa5; write_cmd(insac, NULL); // request sa 900 insb8[4]=0x06; write_cmd(insb8, NULL); // read sa 901 l_sa=b2i(4, cta_res+2); 902 903 insac[2]=0xa7; write_cmd(insac, NULL); // request name 904 insb8[4]=0x02; write_cmd(insb8, NULL); // read name nano + len 905 l=cta_res[1]; 906 insb8[4]=l; write_cmd(insb8, NULL); // read name 907 cta_res[l]=0; 908 trim((char *)cta_res); 909 if (cta_res[0]) 910 snprintf((char *)l_name, sizeof(l_name), ", name: %s", cta_res); 911 else 912 l_name[0]=0; 913 914 // read GEO 915 insac[2]=0xa6; write_cmd(insac, NULL); // request GEO 916 insb8[4]=0x02; write_cmd(insb8, NULL); // read GEO nano + len 917 l=cta_res[1]; 918 insb8[4]=l; write_cmd(insb8, NULL); // read geo 919 cs_ri_log(reader, "provider: %d, id: %06X%s, sa: %08X, geo: %s", 920 i, l_provid, l_name, l_sa, (l<4) ? "empty" : cs_hexdump(1, cta_res, l)); 921 922 // read classes subscription 923 insac[2]=0xa9; insac[4]=4; 924 write_cmd(insac, cls); // request class subs 925 scls=0; 926 while( (cta_res[cta_lr-2]==0x90) && (cta_res[cta_lr-1]==0) ) 927 { 928 insb8[4]=0x02; write_cmd(insb8, NULL); // read class subs nano + len 929 if( (cta_res[cta_lr-2]==0x90) && (cta_res[cta_lr-1]==0) ) 930 { 931 int32_t fshow; 932 l=cta_res[1]; 933 //fshow=(client[cs_idx].dbglvl==D_DUMP)?1:(scls < show_cls)?1:0; 934 fshow=(scls<show_cls); 935 insb8[4]=l; write_cmd(insb8, NULL); // read class subs 936 if( (cta_res[cta_lr-2]==0x90) && (fshow) && 937 (cta_res[cta_lr-1]==0x00 || cta_res[cta_lr-1]==0x08) ) 938 { 939 show_class(reader, NULL, cta_res, cta_lr-2); 940 scls++; 941 } 942 } 943 } 944 945 insac[4]=0; 946 insa4[2]=0x02; 947 write_cmd(insa4, NULL); // select next provider 948 } 949 //return ERROR; 950 return OK; 942 951 } 943 952 … … 967 976 //cs_ddump_mask(D_READER, buffer, len, "viaccess global emm:"); 968 977 return 0; 969 978 970 979 case 0x8e: 971 980 // emm-s part 2 … … 982 991 pos+=emm_global[i+1]+2; 983 992 } 984 993 985 994 if (buffer[2]==0x2c) { 986 995 //add 9E 20 nano + first 32 bytes of emm content
Note:
See TracChangeset
for help on using the changeset viewer.