2 #ifdef READER_CRYPTOWORKS
3 #include "cscrypt/bn.h"
4 #include "oscam-config.h"
6 #include "reader-common.h"
9 struct cryptoworks_data
18 static const char *cs_cert
= "oscam.cert";
20 static int search_boxkey(struct s_reader
*rdr
, uint16_t caid
, char *key
)
26 fp
= fopen(get_config_filename(c_caid
, sizeof(c_caid
), cs_cert
), "r");
29 for(; (!rc
) && fgets(c_caid
, sizeof(c_caid
), fp
);)
31 char *c_provid
, *c_key
;
33 c_provid
= strchr(c_caid
, '#');
36 if(!(c_provid
= strchr(c_caid
, ':')))
39 if(!(c_key
= strchr(c_provid
, ':')))
42 if(word_atob(trim(c_caid
)) != caid
)
44 if((i
= (cs_strlen(trim(c_key
)) >> 1)) > 256)
46 if(cs_atob((uint8_t *)key
, c_key
, i
) < 0)
48 rdr_log(rdr
, "ERROR: wrong key in \"%s\"", cs_cert
);
58 static void RotateBytes1(uint8_t *out
, uint8_t *in
, int32_t n
)
60 // loop is executed atleast once, so it's not a good idea to
70 static void RotateBytes2(uint8_t *in
, int32_t n
)
72 // loop is executed atleast once, so it's not a good idea to
74 uint8_t *e
= in
+ n
- 1;
84 static int32_t Input(BIGNUM
*d
, uint8_t *in
, int32_t n
, int32_t LE
)
89 RotateBytes1(tmp
, in
, n
);
90 return (BN_bin2bn(tmp
, n
, d
) != 0);
93 { return (BN_bin2bn(in
, n
, d
) != 0); }
96 static int32_t Output(struct s_reader
*reader
, uint8_t *out
, int32_t n
, BIGNUM
*r
, int32_t LE
)
98 int32_t s
= BN_num_bytes(r
);
102 rdr_log_dbg(reader
, D_READER
, "rsa: RSA len %d > %d, truncating", s
, n
);
104 memcpy(out
, buff
+ s
- n
, n
);
109 rdr_log_dbg(reader
, D_READER
, "rsa: RSA len %d < %d, padding", s
, n
);
111 BN_bn2bin(r
, out
+ l
);
114 { BN_bn2bin(r
, out
); }
116 { RotateBytes2(out
, n
); }
120 static int32_t cw_RSA(struct s_reader
*reader
, uint8_t *out
, uint8_t *in
, int32_t n
, BIGNUM
*exp
, BIGNUM
*mod
, int32_t LE
)
128 if(Input(d
, in
, n
, LE
))
130 if(BN_mod_exp(r
, d
, exp
, mod
, ctx
))
131 { rc
= Output(reader
, out
, n
, r
, LE
); }
133 { rdr_log(reader
, "rsa: mod-exp failed"); }
141 static time_t chid_date(uint8_t *ptr
, char *buf
, int32_t l
)
145 memset(&timeinfo
, 0, sizeof(struct tm
));
148 timeinfo
.tm_year
= 90 + (ptr
[0] >> 1);
149 timeinfo
.tm_mon
= (((ptr
[0] & 1) << 3) | (ptr
[1] >> 5)) - 1;
150 timeinfo
.tm_mday
= ptr
[1] & 0x1f;
151 rc
= mktime(&timeinfo
);
152 strftime(buf
, l
, "%Y/%m/%d", &timeinfo
);
158 static int32_t select_file(struct s_reader
*reader
, uint8_t f1
, uint8_t f2
, uint8_t *cta_res
, uint16_t *p_cta_lr
)
161 uint8_t insA4
[] = { 0xA4, 0xA4, 0x00, 0x00, 0x02, 0x00, 0x00 };
164 write_cmd(insA4
, insA4
+ 5); // select file
166 return ((cta_res
[0] == 0x9f) && (cta_res
[1] == 0x11));
169 static int32_t read_record(struct s_reader
*reader
, uint8_t rec
, uint8_t *cta_res
)
172 uint8_t insA2
[] = { 0xA4, 0xA2, 0x00, 0x00, 0x01, 0x00 };
173 uint8_t insB2
[] = { 0xA4, 0xB2, 0x00, 0x00, 0x00 };
176 write_cmd(insA2
, insA2
+ 5); // select record
177 if(cta_res
[0] != 0x9f)
179 insB2
[4] = cta_res
[1]; // get len
180 write_cmd(insB2
, NULL
); // read record
181 if((cta_res
[cta_lr
- 2] != 0x90) || (cta_res
[cta_lr
- 1]))
187 int32_t cryptoworks_send_pin(struct s_reader * reader)
189 uint8_t insPIN[] = { 0xA4, 0x20, 0x00, 0x00, 0x04, 0x00,0x00,0x00,0x00 }; //Verify PIN
191 if(reader->pincode[0] && (reader->pincode[0]&0xF0)==0x30)
193 memcpy(insPIN+5,reader->pincode,4);
195 write_cmd(insPIN, insPIN+5);
196 rdr_log_dbg(reader, D_READER, "Sent pincode to card.");
197 if((cta_res[0]==0x98)&&(cta_res[1]==0x04)) rdr_log(reader, "bad pincode");
206 static int32_t cryptoworks_disable_pin(struct s_reader
*reader
)
209 uint8_t insPIN
[] = { 0xA4, 0x26, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00 }; // disable PIN
211 if(reader
->pincode
[0] && (reader
->pincode
[0] & 0xF0) == 0x30)
213 memcpy(insPIN
+ 5, reader
->pincode
, 4);
215 write_cmd(insPIN
, insPIN
+ 5);
216 rdr_log(reader
, "disable pincode to card");
217 if((cta_res
[0] == 0x98) && (cta_res
[1] == 0x04)) { rdr_log(reader
, "bad pincode"); }
223 static int32_t cryptoworks_card_init(struct s_reader
*reader
, ATR
*newatr
)
228 uint32_t mfid
= 0x3F20;
229 static const uint8_t cwexp
[] = { 1, 0 , 1 };
230 uint8_t insA4C
[] = { 0xA4, 0xC0, 0x00, 0x00, 0x11 };
231 uint8_t insB8
[] = { 0xA4, 0xB8, 0x00, 0x00, 0x0C };
232 uint8_t issuerid
= 0;
233 char issuer
[20] = { 0 }, tmp
[11];
234 char *unknown
= "unknown", *pin
= unknown
, ptxt
[CS_MAXPROV
<< 2] = {0};
236 if((atr
[6] != 0xC4) || (atr
[9] != 0x8F) || (atr
[10] != 0xF1)) { return ERROR
; }
238 if(!cs_malloc(&reader
->csystem_data
, sizeof(struct cryptoworks_data
)))
240 struct cryptoworks_data
*csystem_data
= reader
->csystem_data
;
242 rdr_log(reader
, "card detected");
243 rdr_log(reader
, "type: CryptoWorks");
245 reader
->caid
= 0xD00;
247 memset(reader
->prid
, 0, sizeof(reader
->prid
));
249 write_cmd(insA4C
, NULL
); // read masterfile-ID
250 if((cta_res
[0] == 0xDF) && (cta_res
[1] >= 6))
251 { mfid
= (cta_res
[6] << 8) | cta_res
[7]; }
253 select_file(reader
, 0x3f, 0x20, cta_res
, &cta_lr
);
254 insB8
[2] = insB8
[3] = 0; // first
255 for(cta_res
[0] = 0xdf; cta_res
[0] == 0xdf;)
257 write_cmd(insB8
, NULL
); // read provider id's
258 if(cta_res
[0] != 0xdf) { break; }
259 if(((cta_res
[4] & 0x1f) == 0x1f) && (reader
->nprov
< CS_MAXPROV
))
261 snprintf(ptxt
+ cs_strlen(ptxt
), sizeof(ptxt
) - cs_strlen(ptxt
), ",%02X", cta_res
[5]);
262 reader
->prid
[reader
->nprov
++][3] = cta_res
[5];
264 insB8
[2] = insB8
[3] = 0xff; // next
266 for(i
= reader
->nprov
; i
< CS_MAXPROV
; i
++)
267 { memset(&reader
->prid
[i
][0], 0xff, 4); }
269 select_file(reader
, 0x2f, 0x01, cta_res
, &cta_lr
); // read caid
270 if(read_record(reader
, 0xD1, cta_res
) >= 4)
271 { reader
->caid
= (cta_res
[2] << 8) | cta_res
[3]; }
273 if(read_record(reader
, 0x80, cta_res
) >= 7) // read serial
274 { memcpy(reader
->hexserial
, cta_res
+ 2, 5); }
275 rdr_log_sensitive(reader
, "type: CryptoWorks, caid: %04X, ascii serial: {%llu}, hex serial: {%s}",
276 reader
->caid
, (unsigned long long) b2ll(5, reader
->hexserial
), cs_hexdump(0, reader
->hexserial
, 5, tmp
, sizeof(tmp
)));
278 if(read_record(reader
, 0x9E, cta_res
) >= 66) // read ISK
282 if(search_boxkey(reader
, reader
->caid
, (char *)keybuf
))
285 BN_bin2bn(cwexp
, sizeof(cwexp
), csystem_data
->exp
);
286 BN_bin2bn(keybuf
, 64, ipk
);
287 cw_RSA(reader
, cta_res
+ 2, cta_res
+ 2, 0x40, csystem_data
->exp
, ipk
, 0);
290 csystem_data
->ucpk_valid
= (cta_res
[2] == ((mfid
& 0xFF) >> 1));
291 if(csystem_data
->ucpk_valid
)
294 BN_bin2bn(cta_res
+ 2, 0x40, csystem_data
->ucpk
);
295 rdr_log_dump_dbg(reader
, D_READER
, cta_res
+ 2, 0x40, "IPK available -> session-key:");
299 csystem_data
->ucpk_valid
= (keybuf
[0] == (((mfid
& 0xFF) >> 1) | 0x80));
300 if(csystem_data
->ucpk_valid
)
302 BN_bin2bn(keybuf
, 0x40, csystem_data
->ucpk
);
303 rdr_log_dump_dbg(reader
, D_READER
, keybuf
, 0x40, "session-key found:");
306 { rdr_log(reader
, "invalid IPK or session-key for CAID %04X !", reader
->caid
); }
310 if(read_record(reader
, 0x9F, cta_res
) >= 3)
311 { issuerid
= cta_res
[2]; }
312 if(read_record(reader
, 0xC0, cta_res
) >= 16)
314 cs_strncpy(issuer
, (const char *)cta_res
+ 2, sizeof(issuer
));
318 { cs_strncpy(issuer
, unknown
, sizeof(issuer
)); }
320 select_file(reader
, 0x3f, 0x20, cta_res
, &cta_lr
);
321 select_file(reader
, 0x2f, 0x11, cta_res
, &cta_lr
); // read pin
323 if(read_record(reader
, atr
[8], cta_res
) >= 7)
326 pin
= (char *)cta_res
+ 2;
328 rdr_log(reader
, "issuer: %s, id: %02X, bios: v%d, pin: %s, mfid: %04X", issuer
, issuerid
, atr
[7], pin
, mfid
);
329 rdr_log(reader
, "providers: %d (%s)", reader
->nprov
, ptxt
+ 1);
331 cryptoworks_disable_pin(reader
);
333 if (((reader
->caid
== 0x0D96) || (reader
->caid
== 0x0D98)) && reader
->needsglobalfirst
== 1)
335 if(!cs_malloc(&reader
->last_g_emm
, sizeof(EMM_PACKET
)))
339 reader
->last_g_emm_valid
= false;
340 rdr_log(reader
, "Init for global EMM handling CAID %04X successful",reader
->caid
);
346 static int32_t cryptoworks_do_ecm(struct s_reader
*reader
, const ECM_REQUEST
*er
, struct s_ecm_answer
*ea
)
350 uint8_t ins4C
[] = { 0xA4, 0x4C, 0x00, 0x00, 0x00 };
351 uint8_t insC0
[] = { 0xA4, 0xC0, 0x00, 0x00, 0x1C };
353 struct cryptoworks_data
*csystem_data
= reader
->csystem_data
;
354 int32_t secLen
= check_sct_len(er
->ecm
, -5 + (csystem_data
->ucpk_valid
? sizeof(nanoD4
) : 0));
359 const uint8_t *ecm
= er
->ecm
;
360 uint8_t buff
[MAX_LEN
];
362 if(csystem_data
->ucpk_valid
)
364 memcpy(buff
, er
->ecm
, secLen
);
367 for(i
= 2; i
< (int)sizeof(nanoD4
); i
++)
368 { nanoD4
[i
] = rand(); }
369 memcpy(&buff
[secLen
], nanoD4
, sizeof(nanoD4
));
371 secLen
+= sizeof(nanoD4
);
374 ins4C
[3] = csystem_data
->ucpk_valid
? 2 : 0;
375 ins4C
[4] = secLen
- 5;
376 write_cmd(ins4C
, ecm
+ 5);
378 if(cta_res
[cta_lr
- 2] == 0x9f)
380 insC0
[4] = cta_res
[cta_lr
- 1];
381 write_cmd(insC0
, NULL
);
383 for(i
= 0; i
< secLen
&& r
< 2;)
385 int32_t n
= cta_res
[i
+ 1];
389 rdr_log_dbg(reader
, D_READER
, "nano 80 (serial)");
393 rdr_log_dbg(reader
, D_READER
, "nano D4 (rand)");
394 if(n
< 8 || memcmp(&cta_res
[i
], nanoD4
, sizeof(nanoD4
)))
396 rdr_log_dbg(reader
, D_READER
, "random data check failed after decrypt");
401 rdr_log_dbg(reader
, D_READER
, "nano DB (cw)");
404 memcpy(ea
->cw
, &cta_res
[i
+ 2], 16);
409 case 0xDF: // signature
410 rdr_log_dbg(reader
, D_READER
, "nano DF %02x (sig)", n
);
413 if((cta_res
[i
+ 2] & 0x50) == 0x50 && !(cta_res
[i
+ 3] & 0x01) && (cta_res
[i
+ 5] & 0x80))
416 else if(n
== 0x40) // camcrypt
418 if(csystem_data
->ucpk_valid
)
420 cw_RSA(reader
, &cta_res
[i
+ 2], &cta_res
[i
+ 2], n
, csystem_data
->exp
, csystem_data
->ucpk
, 0);
421 rdr_log_dbg(reader
, D_READER
, "after camcrypt");
428 rdr_log(reader
, "valid UCPK needed for camcrypt!");
435 rdr_log_dbg(reader
, D_READER
, "nano %02x (unhandled)", cta_res
[i
]);
444 if ((cta_res[cta_lr-2]==0x9f)&&(cta_res[cta_lr-1]==0x1c))
446 write_cmd(insC0, NULL);
447 if ((cta_lr>26)&&(cta_res[cta_lr-2]==0x90)&&(cta_res[cta_lr-1]==0))
449 if (rc=(((cta_res[20]&0x50)==0x50) &&
450 (!(cta_res[21]&0x01)) &&
452 memcpy(ea->cw, cta_res+2, 16);
459 //return(rc ? 1 : 0);
460 return ((r
== 3) ? 1 : 0);
463 static uint32_t cryptoworks_get_emm_provid(uint8_t *buffer
, int32_t len
)
473 provid
= buffer
[i
+ 2] & 0xfc;
478 i
+= buffer
[i
+ 1] + 2;
486 static int32_t cryptoworks_get_emm_type(EMM_PACKET
*ep
, struct s_reader
*rdr
)
488 char dumprdrserial
[16], dumpemmserial
[16];
490 rdr_log_dbg(rdr
, D_EMM
, "Entered cryptoworks_get_emm_type ep->emm[0]=%02x", ep
->emm
[0]);
494 if(ep
->emm
[3] == 0xA9 && ep
->emm
[4] == 0xFF && ep
->emm
[13] == 0x80 && ep
->emm
[14] == 0x05)
497 memset(ep
->hexserial
, 0, 8);
498 memcpy(ep
->hexserial
, ep
->emm
+ 5, 5);
500 if(cs_dblevel
& D_EMM
)
502 cs_hexdump(1, rdr
->hexserial
, 5, dumprdrserial
, sizeof(dumprdrserial
));
503 cs_hexdump(1, ep
->hexserial
, 5, dumpemmserial
, sizeof(dumpemmserial
));
506 i2b_buf(4, cryptoworks_get_emm_provid(ep
->emm
+ 12, ep
->emmlen
- 12), ep
->provid
);
507 rdr_log_dbg_sensitive(rdr
, D_EMM
, "UNIQUE, ep = {%s} rdr = {%s}", dumpemmserial
, dumprdrserial
);
508 return (!memcmp(ep
->emm
+ 5, rdr
->hexserial
, 5)); // check for serial
513 if(ep
->emm
[3] == 0xA9 && ep
->emm
[4] == 0xFF && ep
->emm
[12] == 0x80 && ep
->emm
[13] == 0x04)
516 memset(ep
->hexserial
, 0, 8);
517 memcpy(ep
->hexserial
, ep
->emm
+ 5, 4);
519 if(cs_dblevel
& D_EMM
)
521 cs_hexdump(1, rdr
->hexserial
, 4, dumprdrserial
, sizeof(dumprdrserial
));
522 cs_hexdump(1, ep
->hexserial
, 4, dumpemmserial
, sizeof(dumpemmserial
));
525 i2b_buf(4, cryptoworks_get_emm_provid(ep
->emm
+ 12, ep
->emmlen
- 12), ep
->provid
);
526 rdr_log_dbg_sensitive(rdr
, D_EMM
, "SHARED, ep = {%s} rdr = {%s}", dumpemmserial
, dumprdrserial
);
527 return (!memcmp(ep
->emm
+ 5, rdr
->hexserial
, 4)); // check for SA
532 if(ep
->emm
[3] == 0xA9 && ep
->emm
[4] == 0xFF && ep
->emm
[5] == 0x83
533 && ep
->emm
[6] == 0x01 && (ep
->emm
[8] == 0x85 || ep
->emm
[8] == 0x84 || ep
->emm
[8] == 0x8C))
535 rdr_log_dbg(rdr
, D_EMM
, "SHARED (Header)");
537 i2b_buf(4, cryptoworks_get_emm_provid(ep
->emm
+ 8, ep
->emmlen
- 8), ep
->provid
);
538 // We need those packets to pass otherwise we would never
539 // be able to complete EMM reassembly
546 if(ep
->emm
[3] == 0xA9 && ep
->emm
[4] == 0xFF && ep
->emm
[8] == 0x83 && ep
->emm
[9] == 0x01)
548 rdr_log_dbg(rdr
, D_EMM
, "GLOBAL");
550 i2b_buf(4, cryptoworks_get_emm_provid(ep
->emm
+ 8, ep
->emmlen
- 8), ep
->provid
);
557 rdr_log_dbg(rdr
, D_EMM
, "0x8F via camd3");
562 i2b_buf(4, cryptoworks_get_emm_provid(ep
->emm
+ 8, ep
->emmlen
- 8), ep
->provid
);
567 i2b_buf(4, cryptoworks_get_emm_provid(ep
->emm
+ 12, ep
->emmlen
- 12), ep
->provid
);
572 i2b_buf(4, cryptoworks_get_emm_provid(ep
->emm
+ 12, ep
->emmlen
- 12), ep
->provid
);
578 /* FIXME: Seems to be that all other EMM types are rejected by the card */
581 rdr_log_dbg(rdr
, D_EMM
, "UNKNOWN");
582 return 0; // skip emm
585 rdr_log_dbg(rdr
, D_EMM
, "invalid");
589 static int32_t cryptoworks_get_emm_filter(struct s_reader
*rdr
, struct s_csystem_emm_filter
**emm_filters
, unsigned int *filter_count
)
591 if(*emm_filters
== NULL
)
593 const unsigned int max_filter_count
= 4;
594 if(!cs_malloc(emm_filters
, max_filter_count
* sizeof(struct s_csystem_emm_filter
)))
597 struct s_csystem_emm_filter
*filters
= *emm_filters
;
602 filters
[idx
].type
= EMM_GLOBAL
;
603 filters
[idx
].enabled
= 1;
604 filters
[idx
].filter
[0] = 0x88;
605 filters
[idx
].mask
[0] = 0xFE;
606 filters
[idx
].filter
[1] = 0xA9;
607 filters
[idx
].mask
[1] = 0xFF;
608 filters
[idx
].filter
[2] = 0xFF;
609 filters
[idx
].mask
[2] = 0xFF;
612 filters
[idx
].type
= EMM_SHARED
;
613 filters
[idx
].enabled
= 1;
614 filters
[idx
].filter
[0] = 0x86;
615 filters
[idx
].mask
[0] = 0xFF;
616 filters
[idx
].filter
[1] = 0xA9;
617 filters
[idx
].mask
[1] = 0xFF;
618 filters
[idx
].filter
[2] = 0xFF;
619 filters
[idx
].mask
[2] = 0xFF;
622 filters
[idx
].type
= EMM_SHARED
;
623 filters
[idx
].enabled
= 1;
624 filters
[idx
].filter
[0] = 0x84;
625 filters
[idx
].mask
[0] = 0xFF;
626 filters
[idx
].filter
[1] = 0xA9;
627 filters
[idx
].mask
[1] = 0xFF;
628 filters
[idx
].filter
[2] = 0xFF;
629 filters
[idx
].mask
[2] = 0xFF;
630 memcpy(&filters
[idx
].filter
[3], rdr
->hexserial
, 4);
631 memset(&filters
[idx
].mask
[3], 0xFF, 4);
634 filters
[idx
].type
= EMM_UNIQUE
;
635 filters
[idx
].enabled
= 1;
636 filters
[idx
].filter
[0] = 0x82;
637 filters
[idx
].mask
[0] = 0xFF;
638 filters
[idx
].filter
[1] = 0xA9;
639 filters
[idx
].mask
[1] = 0xFF;
640 filters
[idx
].filter
[2] = 0xFF;
641 filters
[idx
].mask
[2] = 0xFF;
642 memcpy(&filters
[idx
].filter
[3], rdr
->hexserial
, 5);
643 memset(&filters
[idx
].mask
[3], 0xFF, 5);
652 static int32_t cryptoworks_do_emm(struct s_reader
*reader
, EMM_PACKET
*ep
)
655 uint8_t insEMM_GA
[] = { 0xA4, 0x44, 0x00, 0x00, 0x00 };
656 uint8_t insEMM_SA
[] = { 0xA4, 0x48, 0x00, 0x00, 0x00 };
657 uint8_t insEMM_UA
[] = { 0xA4, 0x42, 0x00, 0x00, 0x00 };
658 uint8_t *emm
= ep
->emm
;
660 if(emm
[0] == 0x8f && emm
[3] == 0xA4)
663 write_cmd(emm
+ 3, emm
+ 3 + CMD_LEN
);
670 insEMM_GA
[4] = ep
->emm
[2] - 2;
671 if(emm
[7] == insEMM_GA
[4] - 3)
673 write_cmd(insEMM_GA
, emm
+ 5);
678 insEMM_SA
[4] = ep
->emm
[2] - 6;
679 if(emm
[11] == insEMM_SA
[4] - 3)
681 write_cmd(insEMM_SA
, emm
+ 9);
686 insEMM_UA
[4] = ep
->emm
[2] - 7;
687 if(emm
[12] == insEMM_UA
[4] - 3)
689 //cryptoworks_send_pin(); //?? may be
690 write_cmd(insEMM_UA
, emm
+ 10);
696 if((cta_res
[0] == 0x90) && (cta_res
[1] == 0x00))
701 // emm already written before, entitlement / key is already up to date -> skipped
702 if((cta_res
[0] == 0x94) && (cta_res
[1] == 0x04))
707 rdr_log_dbg(reader
, D_EMM
, "%s(): type %d - response %02X %02X",
708 __func__
, ep
->type
, cta_res
[0], cta_res
[1]);
713 static int32_t cryptoworks_card_info(struct s_reader
*reader
)
717 uint8_t insA21
[] = { 0xA4, 0xA2, 0x01, 0x00, 0x05, 0x8C, 0x00, 0x00, 0x00, 0x00 };
718 uint8_t insB2
[] = { 0xA4, 0xB2, 0x00, 0x00, 0x00 };
719 char l_name
[20 + 8] = ", name: ";
721 cs_clear_entitlement(reader
); // reset the entitlements
723 for(i
= 0; i
< reader
->nprov
; i
++)
726 select_file(reader
, 0x1f, reader
->prid
[i
][3], cta_res
, &cta_lr
); // select provider
727 select_file(reader
, 0x0e, 0x11, cta_res
, &cta_lr
); // read provider name
729 if(read_record(reader
, 0xD6, cta_res
) >= 16)
731 cs_strncpy(l_name
+ 8, (const char *)cta_res
+ 2, sizeof(l_name
) - 8);
732 l_name
[sizeof(l_name
) - 1] = 0;
736 l_name
[0] = (l_name
[8]) ? ',' : 0;
737 rdr_log(reader
, "provider: %d, id: %02X%s", i
+ 1, reader
->prid
[i
][3], l_name
);
738 select_file(reader
, 0x0f, 0x20, cta_res
, &cta_lr
); // select provider class
739 write_cmd(insA21
, insA21
+ 5);
741 if(cta_res
[0] == 0x9f)
743 insB2
[4] = cta_res
[1];
744 for(insB2
[3] = 0; (cta_res
[0] != 0x94) || (cta_res
[1] != 0x2); insB2
[3] = 1)
746 write_cmd(insB2
, NULL
); // read chid
747 if(cta_res
[0] != 0x94)
751 // todo: add entitlements to list but produces a warning related to date variable
752 cs_add_entitlement(reader
, reader
->caid
, reader
->prid
[i
][3], b2i(2, cta_res
+ 6), 0,
753 chid_date(cta_res
+ 28, ds
, sizeof(ds
) - 1),
754 chid_date(cta_res
+ 30, de
, sizeof(de
) - 1), 3, 1);
756 rdr_log(reader
, "chid: %02X%02X, date: %s - %s, name: %s",
757 cta_res
[6], cta_res
[7], ds
, de
, trim((char *) cta_res
+ 10));
762 select_file(reader
, 0x0f, 0x00, cta_res
, &cta_lr
); // select provider channel
763 write_cmd(insA21
, insA21
+ 5);
765 if(cta_res
[0] == 0x9f)
767 insB2
[4] = cta_res
[1];
768 for(insB2
[3] = 0; (cta_res
[0] != 0x94) || (cta_res
[1] != 0x2); insB2
[3] = 1)
770 write_cmd(insB2
, NULL
); // read chid
771 if(cta_res
[0] != 0x94)
775 // todo: add entitlements to list but produces a warning related to date variable
776 cs_add_entitlement(reader
, reader
->caid
, reader
->prid
[i
][3], b2i(2, cta_res
+ 6), 0,
777 chid_date(cta_res
+ 28, ds
, sizeof(ds
) - 1),
778 chid_date(cta_res
+ 30, de
, sizeof(de
) - 1), 3, 1);
781 rdr_log(reader
, "chid: %02X%02X, date: %s - %s, name: %s",
782 cta_res
[6], cta_res
[7], ds
, de
, trim((char *)cta_res
+ 10));
787 rdr_log(reader
, "ready for requests");
791 static int32_t cryptoworks_reassemble_emm(struct s_reader
*rdr
, struct s_client
*client
, EMM_PACKET
*ep
)
793 uint8_t *buffer
= ep
->emm
;
794 int16_t *len
= &ep
->emmlen
;
798 // Cryptoworks EMM-S have to be assembled by the client from an EMM-SH with table
799 // id 0x84 and a corresponding EMM-SB (body) with table id 0x86. A pseudo EMM-S
800 // with table id 0x84 has to be build containing all nano commands from both the
801 // original EMM-SH and EMM-SB in ascending order.
803 if(*len
> 500) { return 0; }
805 if (!client
->cw_rass
&& !cs_malloc(&client
->cw_rass
, sizeof(*client
->cw_rass
)))
807 cs_log("[cryptoworks] ERROR: Can't allocate EMM reassembly buffer.");
810 struct emm_rass
*r_emm
= client
->cw_rass
;
815 rdr_log_dbg(rdr
, D_EMM
, "unique emm (EMM-U)");
819 rdr_log_dbg(rdr
, D_EMM
, "shared emm (EMM-SH)");
820 if(!memcmp(r_emm
->emm
, buffer
, *len
))
823 if(ep
->emm
[11] == ep
->emm
[2] - 9)
825 rdr_log_dbg(rdr
, D_EMM
, "received assembled EMM-S");
829 memcpy(r_emm
->emm
, buffer
, *len
);
830 r_emm
->emmlen
= *len
;
831 rdr_log_dbg(rdr
, D_EMM
, "EMM-SH only in memcpy");
835 rdr_log_dbg(rdr
, D_EMM
, "shared emm (EMM-SB)");
839 // we keep the first 12 bytes of the 0x84 emm (EMM-SH)
840 // now we need to append the payload of the 0x86 emm (EMM-SB)
841 // starting after the header (&buffer[5])
842 // then the rest of the payload from EMM-SH
843 // so we should have :
844 // EMM-SH[0:12] + EMM-SB[5:len_EMM-SB] + EMM-SH[12:EMM-SH_len]
845 // then sort the nano in ascending order
846 // update the emm len (emmBuf[1:2])
849 emm_len
= *len
- 5 + r_emm
->emmlen
- 12;
850 uint8_t *tmp
, *assembled
;
851 if(!cs_malloc(&tmp
, emm_len
))
853 if(!cs_malloc(&assembled
, emm_len
+ 12))
858 uint8_t *assembled_EMM
;
859 if(!cs_malloc(&assembled_EMM
, emm_len
+ 12))
865 memcpy(tmp
, &buffer
[5], *len
- 5);
866 memcpy(tmp
+ *len
- 5, &r_emm
->emm
[12], r_emm
->emmlen
- 12);
867 memcpy(assembled_EMM
, r_emm
->emm
, 12);
868 emm_sort_nanos(assembled_EMM
+ 12, tmp
, emm_len
);
870 assembled_EMM
[1] = ((emm_len
+ 9) >> 8) | 0x70;
871 assembled_EMM
[2] = (emm_len
+ 9) & 0xFF;
873 if(assembled_EMM
[11] != emm_len
) // sanity check
875 // error in emm assembly
876 rdr_log_dbg(rdr
, D_EMM
, "Error assembling EMM-S");
881 //copy back the assembled emm in the working buffer
882 memcpy(buffer
, assembled_EMM
, emm_len
+ 12);
890 rdr_log_dump_dbg(rdr
, D_EMM
, buffer
, *len
, "shared emm (assembled):");
896 rdr_log_dbg(rdr
, D_EMM
, "global emm (EMM-G)");
902 const struct s_cardsystem reader_cryptoworks
=
904 .desc
= "cryptoworks",
905 .caids
= (uint16_t[]){ 0x0D, 0 },
906 .do_emm_reassembly
= cryptoworks_reassemble_emm
,
907 .do_emm
= cryptoworks_do_emm
,
908 .do_ecm
= cryptoworks_do_ecm
,
909 .card_info
= cryptoworks_card_info
,
910 .card_init
= cryptoworks_card_init
,
911 .get_emm_type
= cryptoworks_get_emm_type
,
912 .get_emm_filter
= cryptoworks_get_emm_filter
,