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
= (strlen(trim(c_key
)) >> 1)) > 256)
46 if(cs_atob((uchar
*)key
, c_key
, i
) < 0)
48 rdr_log(rdr
, "ERROR: wrong key in \"%s\"", cs_cert
);
58 static void RotateBytes1(unsigned char *out
, unsigned char *in
, int32_t n
)
60 // loop is executed atleast once, so it's not a good idea to
70 static void RotateBytes2(unsigned char *in
, int32_t n
)
72 // loop is executed atleast once, so it's not a good idea to
74 unsigned char *e
= in
+ n
- 1;
77 unsigned char temp
= *in
;
84 static int32_t Input(BIGNUM
*d
, unsigned char *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
, unsigned char *out
, int32_t n
, BIGNUM
*r
, int32_t LE
)
98 int32_t s
= BN_num_bytes(r
);
101 unsigned char buff
[s
];
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
, unsigned char *out
, unsigned char *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(uchar
*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
, uchar f1
, uchar f2
, uchar
*cta_res
, uint16_t *p_cta_lr
)
161 uchar 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
, uchar rec
, uchar
*cta_res
)
172 uchar insA2
[] = {0xA4, 0xA2, 0x00, 0x00, 0x01, 0x00};
173 uchar 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 unsigned char 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 unsigned char 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 uchar cwexp
[] = { 1, 0 , 1};
230 uchar insA4C
[] = {0xA4, 0xC0, 0x00, 0x00, 0x11};
231 uchar insB8
[] = {0xA4, 0xB8, 0x00, 0x00, 0x0c};
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
+ strlen(ptxt
), sizeof(ptxt
) - 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);
289 csystem_data
->ucpk_valid
= (cta_res
[2] == ((mfid
& 0xFF) >> 1));
290 if(csystem_data
->ucpk_valid
)
293 BN_bin2bn(cta_res
+ 2, 0x40, csystem_data
->ucpk
);
294 rdr_log_dump_dbg(reader
, D_READER
, cta_res
+ 2, 0x40, "IPK available -> session-key:");
298 csystem_data
->ucpk_valid
= (keybuf
[0] == (((mfid
& 0xFF) >> 1) | 0x80));
299 if(csystem_data
->ucpk_valid
)
301 BN_bin2bn(keybuf
, 0x40, csystem_data
->ucpk
);
302 rdr_log_dump_dbg(reader
, D_READER
, keybuf
, 0x40, "session-key found:");
305 { rdr_log(reader
, "invalid IPK or session-key for CAID %04X !", reader
->caid
); }
309 if(read_record(reader
, 0x9F, cta_res
) >= 3)
310 { issuerid
= cta_res
[2]; }
311 if(read_record(reader
, 0xC0, cta_res
) >= 16)
313 cs_strncpy(issuer
, (const char *)cta_res
+ 2, sizeof(issuer
));
317 { cs_strncpy(issuer
, unknown
, sizeof(issuer
)); }
319 select_file(reader
, 0x3f, 0x20, cta_res
, &cta_lr
);
320 select_file(reader
, 0x2f, 0x11, cta_res
, &cta_lr
); // read pin
321 if(read_record(reader
, atr
[8], cta_res
) >= 7)
324 pin
= (char *)cta_res
+ 2;
326 rdr_log(reader
, "issuer: %s, id: %02X, bios: v%d, pin: %s, mfid: %04X", issuer
, issuerid
, atr
[7], pin
, mfid
);
327 rdr_log(reader
, "providers: %d (%s)", reader
->nprov
, ptxt
+ 1);
329 cryptoworks_disable_pin(reader
);
334 static int32_t cryptoworks_do_ecm(struct s_reader
*reader
, const ECM_REQUEST
*er
, struct s_ecm_answer
*ea
)
338 unsigned char ins4C
[] = { 0xA4, 0x4C, 0x00, 0x00, 0x00 };
339 unsigned char insC0
[] = { 0xA4, 0xC0, 0x00, 0x00, 0x1C };
340 unsigned char nanoD4
[10];
341 struct cryptoworks_data
*csystem_data
= reader
->csystem_data
;
342 int32_t secLen
= check_sct_len(er
->ecm
, -5 + (csystem_data
->ucpk_valid
? sizeof(nanoD4
) : 0));
347 const uchar
*ecm
= er
->ecm
;
350 if(csystem_data
->ucpk_valid
)
352 memcpy(buff
, er
->ecm
, secLen
);
355 for(i
= 2; i
< (int)sizeof(nanoD4
); i
++)
356 { nanoD4
[i
] = rand(); }
357 memcpy(&buff
[secLen
], nanoD4
, sizeof(nanoD4
));
359 secLen
+= sizeof(nanoD4
);
362 ins4C
[3] = csystem_data
->ucpk_valid
? 2 : 0;
363 ins4C
[4] = secLen
- 5;
364 write_cmd(ins4C
, ecm
+ 5);
365 if(cta_res
[cta_lr
- 2] == 0x9f)
367 insC0
[4] = cta_res
[cta_lr
- 1];
368 write_cmd(insC0
, NULL
);
369 for(i
= 0; i
< secLen
&& r
< 2;)
371 int32_t n
= cta_res
[i
+ 1];
375 rdr_log_dbg(reader
, D_READER
, "nano 80 (serial)");
378 rdr_log_dbg(reader
, D_READER
, "nano D4 (rand)");
379 if(n
< 8 || memcmp(&cta_res
[i
], nanoD4
, sizeof(nanoD4
)))
381 rdr_log_dbg(reader
, D_READER
, "random data check failed after decrypt");
385 rdr_log_dbg(reader
, D_READER
, "nano DB (cw)");
388 memcpy(ea
->cw
, &cta_res
[i
+ 2], 16);
392 case 0xDF: // signature
393 rdr_log_dbg(reader
, D_READER
, "nano DF %02x (sig)", n
);
396 if((cta_res
[i
+ 2] & 0x50) == 0x50 && !(cta_res
[i
+ 3] & 0x01) && (cta_res
[i
+ 5] & 0x80))
399 else if(n
== 0x40) // camcrypt
401 if(csystem_data
->ucpk_valid
)
403 cw_RSA(reader
, &cta_res
[i
+ 2], &cta_res
[i
+ 2], n
, csystem_data
->exp
, csystem_data
->ucpk
, 0);
404 rdr_log_dbg(reader
, D_READER
, "after camcrypt");
411 rdr_log(reader
, "valid UCPK needed for camcrypt!");
417 rdr_log_dbg(reader
, D_READER
, "nano %02x (unhandled)", cta_res
[i
]);
426 if ((cta_res[cta_lr-2]==0x9f)&&(cta_res[cta_lr-1]==0x1c))
428 write_cmd(insC0, NULL);
429 if ((cta_lr>26)&&(cta_res[cta_lr-2]==0x90)&&(cta_res[cta_lr-1]==0))
431 if (rc=(((cta_res[20]&0x50)==0x50) &&
432 (!(cta_res[21]&0x01)) &&
434 memcpy(ea->cw, cta_res+2, 16);
440 //return(rc ? 1 : 0);
441 return ((r
== 3) ? 1 : 0);
444 static uint32_t cryptoworks_get_emm_provid(unsigned char *buffer
, int32_t len
)
454 provid
= buffer
[i
+ 2] & 0xfc;
458 i
+= buffer
[i
+ 1] + 2;
466 static int32_t cryptoworks_get_emm_type(EMM_PACKET
*ep
, struct s_reader
*rdr
)
468 char dumprdrserial
[16], dumpemmserial
[16];
470 rdr_log_dbg(rdr
, D_EMM
, "Entered cryptoworks_get_emm_type ep->emm[0]=%02x", ep
->emm
[0]);
474 if(ep
->emm
[3] == 0xA9 && ep
->emm
[4] == 0xFF && ep
->emm
[13] == 0x80 && ep
->emm
[14] == 0x05)
477 memset(ep
->hexserial
, 0, 8);
478 memcpy(ep
->hexserial
, ep
->emm
+ 5, 5);
479 cs_hexdump(1, rdr
->hexserial
, 5, dumprdrserial
, sizeof(dumprdrserial
));
480 cs_hexdump(1, ep
->hexserial
, 5, dumpemmserial
, sizeof(dumpemmserial
));
481 i2b_buf(4, cryptoworks_get_emm_provid(ep
->emm
+ 12, ep
->emmlen
- 12), ep
->provid
);
482 rdr_log_dbg_sensitive(rdr
, D_EMM
, "UNIQUE, ep = {%s} rdr = {%s}", dumpemmserial
, dumprdrserial
);
483 return (!memcmp(ep
->emm
+ 5, rdr
->hexserial
, 5)); // check for serial
487 if(ep
->emm
[3] == 0xA9 && ep
->emm
[4] == 0xFF && ep
->emm
[12] == 0x80 && ep
->emm
[13] == 0x04)
490 memset(ep
->hexserial
, 0, 8);
491 memcpy(ep
->hexserial
, ep
->emm
+ 5, 4);
492 cs_hexdump(1, rdr
->hexserial
, 4, dumprdrserial
, sizeof(dumprdrserial
));
493 cs_hexdump(1, ep
->hexserial
, 4, dumpemmserial
, sizeof(dumpemmserial
));
494 i2b_buf(4, cryptoworks_get_emm_provid(ep
->emm
+ 12, ep
->emmlen
- 12), ep
->provid
);
495 rdr_log_dbg_sensitive(rdr
, D_EMM
, "SHARED, ep = {%s} rdr = {%s}", dumpemmserial
, dumprdrserial
);
496 return (!memcmp(ep
->emm
+ 5, rdr
->hexserial
, 4)); // check for SA
500 if(ep
->emm
[3] == 0xA9 && ep
->emm
[4] == 0xFF && ep
->emm
[5] == 0x83
501 && ep
->emm
[6] == 0x01 && (ep
->emm
[8] == 0x85 || ep
->emm
[8] == 0x84 || ep
->emm
[8] == 0x8C))
503 rdr_log_dbg(rdr
, D_EMM
, "SHARED (Header)");
505 i2b_buf(4, cryptoworks_get_emm_provid(ep
->emm
+ 8, ep
->emmlen
- 8), ep
->provid
);
506 // We need those packets to pass otherwise we would never
507 // be able to complete EMM reassembly
513 if(ep
->emm
[3] == 0xA9 && ep
->emm
[4] == 0xFF && ep
->emm
[8] == 0x83 && ep
->emm
[9] == 0x01)
515 rdr_log_dbg(rdr
, D_EMM
, "GLOBAL");
517 i2b_buf(4, cryptoworks_get_emm_provid(ep
->emm
+ 8, ep
->emmlen
- 8), ep
->provid
);
523 rdr_log_dbg(rdr
, D_EMM
, "0x8F via camd3");
528 i2b_buf(4, cryptoworks_get_emm_provid(ep
->emm
+ 8, ep
->emmlen
- 8), ep
->provid
);
532 i2b_buf(4, cryptoworks_get_emm_provid(ep
->emm
+ 12, ep
->emmlen
- 12), ep
->provid
);
536 i2b_buf(4, cryptoworks_get_emm_provid(ep
->emm
+ 12, ep
->emmlen
- 12), ep
->provid
);
542 /* FIXME: Seems to be that all other EMM types are rejected by the card */
545 rdr_log_dbg(rdr
, D_EMM
, "UNKNOWN");
546 return 0; // skip emm
549 rdr_log_dbg(rdr
, D_EMM
, "invalid");
553 static int32_t cryptoworks_get_emm_filter(struct s_reader
*rdr
, struct s_csystem_emm_filter
**emm_filters
, unsigned int *filter_count
)
555 if(*emm_filters
== NULL
)
557 const unsigned int max_filter_count
= 4;
558 if(!cs_malloc(emm_filters
, max_filter_count
* sizeof(struct s_csystem_emm_filter
)))
561 struct s_csystem_emm_filter
*filters
= *emm_filters
;
566 filters
[idx
].type
= EMM_GLOBAL
;
567 filters
[idx
].enabled
= 1;
568 filters
[idx
].filter
[0] = 0x88;
569 filters
[idx
].mask
[0] = 0xFE;
570 filters
[idx
].filter
[1] = 0xA9;
571 filters
[idx
].mask
[1] = 0xFF;
572 filters
[idx
].filter
[2] = 0xFF;
573 filters
[idx
].mask
[2] = 0xFF;
576 filters
[idx
].type
= EMM_SHARED
;
577 filters
[idx
].enabled
= 1;
578 filters
[idx
].filter
[0] = 0x86;
579 filters
[idx
].mask
[0] = 0xFF;
580 filters
[idx
].filter
[1] = 0xA9;
581 filters
[idx
].mask
[1] = 0xFF;
582 filters
[idx
].filter
[2] = 0xFF;
583 filters
[idx
].mask
[2] = 0xFF;
586 filters
[idx
].type
= EMM_SHARED
;
587 filters
[idx
].enabled
= 1;
588 filters
[idx
].filter
[0] = 0x84;
589 filters
[idx
].mask
[0] = 0xFF;
590 filters
[idx
].filter
[1] = 0xA9;
591 filters
[idx
].mask
[1] = 0xFF;
592 filters
[idx
].filter
[2] = 0xFF;
593 filters
[idx
].mask
[2] = 0xFF;
594 memcpy(&filters
[idx
].filter
[3], rdr
->hexserial
, 4);
595 memset(&filters
[idx
].mask
[3], 0xFF, 4);
598 filters
[idx
].type
= EMM_UNIQUE
;
599 filters
[idx
].enabled
= 1;
600 filters
[idx
].filter
[0] = 0x82;
601 filters
[idx
].mask
[0] = 0xFF;
602 filters
[idx
].filter
[1] = 0xA9;
603 filters
[idx
].mask
[1] = 0xFF;
604 filters
[idx
].filter
[2] = 0xFF;
605 filters
[idx
].mask
[2] = 0xFF;
606 memcpy(&filters
[idx
].filter
[3], rdr
->hexserial
, 5);
607 memset(&filters
[idx
].mask
[3], 0xFF, 5);
616 static int32_t cryptoworks_do_emm(struct s_reader
*reader
, EMM_PACKET
*ep
)
619 uchar insEMM_GA
[] = {0xA4, 0x44, 0x00, 0x00, 0x00};
620 uchar insEMM_SA
[] = {0xA4, 0x48, 0x00, 0x00, 0x00};
621 uchar insEMM_UA
[] = {0xA4, 0x42, 0x00, 0x00, 0x00};
622 uchar
*emm
= ep
->emm
;
624 if(emm
[0] == 0x8f && emm
[3] == 0xA4)
627 write_cmd(emm
+ 3, emm
+ 3 + CMD_LEN
);
635 insEMM_GA
[4] = ep
->emm
[2] - 2;
636 if(emm
[7] == insEMM_GA
[4] - 3)
638 write_cmd(insEMM_GA
, emm
+ 5);
644 insEMM_SA
[4] = ep
->emm
[2] - 6;
645 if(emm
[11] == insEMM_SA
[4] - 3)
647 write_cmd(insEMM_SA
, emm
+ 9);
653 insEMM_UA
[4] = ep
->emm
[2] - 7;
654 if(emm
[12] == insEMM_UA
[4] - 3)
656 //cryptoworks_send_pin(); //?? may be
657 write_cmd(insEMM_UA
, emm
+ 10);
663 if((cta_res
[0] == 0x90) && (cta_res
[1] == 0x00))
667 if((cta_res
[0] == 0x94) && (cta_res
[1] == 0x04)) // emm already written before, entitlement / key is already up to date -> skipped
672 rdr_log_dbg(reader
, D_EMM
, "%s(): type %d - response %02X %02X", __func__
, ep
->type
, cta_res
[0], cta_res
[1]);
676 static int32_t cryptoworks_card_info(struct s_reader
*reader
)
680 uchar insA21
[] = {0xA4, 0xA2, 0x01, 0x00, 0x05, 0x8C, 0x00, 0x00, 0x00, 0x00};
681 uchar insB2
[] = {0xA4, 0xB2, 0x00, 0x00, 0x00};
682 char l_name
[20 + 8] = ", name: ";
684 cs_clear_entitlement(reader
); // reset the entitlements
686 for(i
= 0; i
< reader
->nprov
; i
++)
689 select_file(reader
, 0x1f, reader
->prid
[i
][3], cta_res
, &cta_lr
); // select provider
690 select_file(reader
, 0x0e, 0x11, cta_res
, &cta_lr
); // read provider name
691 if(read_record(reader
, 0xD6, cta_res
) >= 16)
693 cs_strncpy(l_name
+ 8, (const char *)cta_res
+ 2, sizeof(l_name
) - 9);
694 l_name
[sizeof(l_name
) - 1] = 0;
697 l_name
[0] = (l_name
[8]) ? ',' : 0;
698 rdr_log(reader
, "provider: %d, id: %02X%s", i
+ 1, reader
->prid
[i
][3], l_name
);
699 select_file(reader
, 0x0f, 0x20, cta_res
, &cta_lr
); // select provider class
700 write_cmd(insA21
, insA21
+ 5);
701 if(cta_res
[0] == 0x9f)
703 insB2
[4] = cta_res
[1];
704 for(insB2
[3] = 0; (cta_res
[0] != 0x94) || (cta_res
[1] != 0x2); insB2
[3] = 1)
706 write_cmd(insB2
, NULL
); // read chid
707 if(cta_res
[0] != 0x94)
711 // todo: add entitlements to list but produces a warning related to date variable
712 cs_add_entitlement(reader
, reader
->caid
, reader
->prid
[i
][3], b2i(2, cta_res
+ 6), 0,
713 chid_date(cta_res
+ 28, ds
, sizeof(ds
) - 1),
714 chid_date(cta_res
+ 30, de
, sizeof(de
) - 1), 3, 1);
716 rdr_log(reader
, "chid: %02X%02X, date: %s - %s, name: %s",
717 cta_res
[6], cta_res
[7], ds
, de
, trim((char *) cta_res
+ 10));
722 select_file(reader
, 0x0f, 0x00, cta_res
, &cta_lr
); // select provider channel
723 write_cmd(insA21
, insA21
+ 5);
724 if(cta_res
[0] == 0x9f)
726 insB2
[4] = cta_res
[1];
727 for(insB2
[3] = 0; (cta_res
[0] != 0x94) || (cta_res
[1] != 0x2); insB2
[3] = 1)
729 write_cmd(insB2
, NULL
); // read chid
730 if(cta_res
[0] != 0x94)
734 // todo: add entitlements to list but produces a warning related to date variable
735 cs_add_entitlement(reader
, reader
->caid
, reader
->prid
[i
][3], b2i(2, cta_res
+ 6), 0,
736 chid_date(cta_res
+ 28, ds
, sizeof(ds
) - 1),
737 chid_date(cta_res
+ 30, de
, sizeof(de
) - 1), 3, 1);
740 rdr_log(reader
, "chid: %02X%02X, date: %s - %s, name: %s",
741 cta_res
[6], cta_res
[7], ds
, de
, trim((char *)cta_res
+ 10));
746 rdr_log(reader
, "ready for requests");
750 static int32_t cryptoworks_reassemble_emm(struct s_reader
*rdr
, struct s_client
*client
, EMM_PACKET
*ep
)
752 uchar
*buffer
= ep
->emm
;
753 int16_t *len
= &ep
->emmlen
;
757 // Cryptoworks EMM-S have to be assembled by the client from an EMM-SH with table
758 // id 0x84 and a corresponding EMM-SB (body) with table id 0x86. A pseudo EMM-S
759 // with table id 0x84 has to be build containing all nano commands from both the
760 // original EMM-SH and EMM-SB in ascending order.
762 if(*len
> 500) { return 0; }
764 if (!client
->cw_rass
&& !cs_malloc(&client
->cw_rass
, sizeof(*client
->cw_rass
)))
766 cs_log("[cryptoworks] ERROR: Can't allocate EMM reassembly buffer.");
769 struct emm_rass
*r_emm
= client
->cw_rass
;
774 rdr_log_dbg(rdr
, D_EMM
, "unique emm (EMM-U)");
778 rdr_log_dbg(rdr
, D_EMM
, "shared emm (EMM-SH)");
779 if(!memcmp(r_emm
->emm
, buffer
, *len
))
782 if(ep
->emm
[11] == ep
->emm
[2] - 9)
784 rdr_log_dbg(rdr
, D_EMM
, "received assembled EMM-S");
788 memcpy(r_emm
->emm
, buffer
, *len
);
789 r_emm
->emmlen
= *len
;
790 rdr_log_dbg(rdr
, D_EMM
, "EMM-SH only in memcpy");
794 rdr_log_dbg(rdr
, D_EMM
, "shared emm (EMM-SB)");
798 // we keep the first 12 bytes of the 0x84 emm (EMM-SH)
799 // now we need to append the payload of the 0x86 emm (EMM-SB)
800 // starting after the header (&buffer[5])
801 // then the rest of the payload from EMM-SH
802 // so we should have :
803 // EMM-SH[0:12] + EMM-SB[5:len_EMM-SB] + EMM-SH[12:EMM-SH_len]
804 // then sort the nano in ascending order
805 // update the emm len (emmBuf[1:2])
808 emm_len
= *len
- 5 + r_emm
->emmlen
- 12;
809 unsigned char *tmp
, *assembled
;
810 if(!cs_malloc(&tmp
, emm_len
))
812 if(!cs_malloc(&assembled
, emm_len
+ 12))
817 unsigned char *assembled_EMM
;
818 if(!cs_malloc(&assembled_EMM
, emm_len
+ 12))
824 memcpy(tmp
, &buffer
[5], *len
- 5);
825 memcpy(tmp
+ *len
- 5, &r_emm
->emm
[12], r_emm
->emmlen
- 12);
826 memcpy(assembled_EMM
, r_emm
->emm
, 12);
827 emm_sort_nanos(assembled_EMM
+ 12, tmp
, emm_len
);
829 assembled_EMM
[1] = ((emm_len
+ 9) >> 8) | 0x70;
830 assembled_EMM
[2] = (emm_len
+ 9) & 0xFF;
832 if(assembled_EMM
[11] != emm_len
) // sanity check
834 // error in emm assembly
835 rdr_log_dbg(rdr
, D_EMM
, "Error assembling EMM-S");
840 //copy back the assembled emm in the working buffer
841 memcpy(buffer
, assembled_EMM
, emm_len
+ 12);
849 rdr_log_dump_dbg(rdr
, D_EMM
, buffer
, *len
, "shared emm (assembled):");
855 rdr_log_dbg(rdr
, D_EMM
, "global emm (EMM-G)");
861 const struct s_cardsystem reader_cryptoworks
=
863 .desc
= "cryptoworks",
864 .caids
= (uint16_t[]){ 0x0D, 0 },
865 .do_emm_reassembly
= cryptoworks_reassemble_emm
,
866 .do_emm
= cryptoworks_do_emm
,
867 .do_ecm
= cryptoworks_do_ecm
,
868 .card_info
= cryptoworks_card_info
,
869 .card_init
= cryptoworks_card_init
,
870 .get_emm_type
= cryptoworks_get_emm_type
,
871 .get_emm_filter
= cryptoworks_get_emm_filter
,