revert breaks some stupid old compilers
[oscam.git] / reader-conax.c
blob95e89e36016aa6bc81985311099072ebbaf68a19
1 #include "globals.h"
2 #ifdef READER_CONAX
3 #include "cscrypt/bn.h"
4 #include "reader-common.h"
6 static int32_t RSA_CNX(struct s_reader *reader, unsigned char *msg, unsigned char *mod, unsigned char *exp, uint32_t cta_lr, uint32_t modbytes, uint32_t expbytes)
8 int32_t ret = 0;
9 uint32_t n = 0, pre_size = 0, size = 0;
10 BN_CTX *ctx;
11 BIGNUM *bn_mod, *bn_exp, *bn_data, *bn_res;
12 unsigned char data[64];
14 /*prefix size*/
15 pre_size = 2 + 4 + msg[5];
16 /*size of data to decryption*/
17 if(msg[1] > (pre_size - 2))
18 { size = msg[1] - pre_size + 2; }
20 if(cta_lr > (pre_size + size) &&
21 size >= modbytes && size < 128)
23 ctx = BN_CTX_new();
25 if(ctx == NULL)
27 rdr_log_dbg(reader, D_READER, "RSA Error in RSA_CNX");
30 BN_CTX_start(ctx);
31 bn_mod = BN_CTX_get(ctx);
32 bn_exp = BN_CTX_get(ctx);
33 bn_data = BN_CTX_get(ctx);
34 bn_res = BN_CTX_get(ctx);
36 /*RSA first round*/
37 BN_bin2bn(mod, modbytes, bn_mod); // rsa modulus
38 BN_bin2bn(exp, expbytes, bn_exp); // exponent
39 BN_bin2bn(msg + pre_size, modbytes, bn_data);
40 BN_mod_exp(bn_res, bn_data, bn_exp, bn_mod, ctx);
42 n = BN_bn2bin(bn_res, data);
44 size -= modbytes; //3
45 pre_size += modbytes;
46 /*Check if second round is needed*/
47 if(0 < size)
49 /*check if length of data from first RSA round will be enough to padding rest of data*/
50 if((n + size) >= modbytes)
52 /*RSA second round*/
53 /*move the remaining data at the beginning of the buffer*/
54 memcpy(msg, msg + pre_size, size);
55 /*padding buffer with data from first round*/
56 memcpy(msg + size, data + (n - (modbytes - size)), modbytes - size);
58 BN_bin2bn(msg, modbytes, bn_data);
59 BN_mod_exp(bn_res, bn_data, bn_exp, bn_mod, ctx);
60 n = BN_bn2bin(bn_res, data);
61 if(0x25 != data[0])
62 { ret = -1; } /*RSA key is probably wrong*/
64 else
65 { ret = -3; } /*wrong size of data for second round*/
68 if(0 == ret)
69 { memcpy(msg, data, n); }
70 BN_CTX_end(ctx);
71 BN_CTX_free(ctx);
73 else
74 { ret = -2; } /*wrong size of data*/
76 return ret;
79 static time_t chid_date(const uchar *ptr, char *buf, int32_t l)
81 time_t rc = 0;
82 struct tm timeinfo;
83 memset(&timeinfo, 0, sizeof(struct tm));
84 if(buf)
86 timeinfo.tm_year = 90 + (ptr[1] >> 4) + (((ptr[0] >> 5) & 7) * 10);
87 timeinfo.tm_mon = (ptr[1] & 0xf) - 1;
88 timeinfo.tm_mday = ptr[0] & 0x1f;
89 timeinfo.tm_isdst = -1;
90 rc = mktime(&timeinfo);
91 strftime(buf, l, "%Y/%m/%d", &timeinfo);
93 return (rc);
96 static int32_t read_record(struct s_reader *reader, const uchar *cmd, const uchar *data, uchar *cta_res)
98 uint16_t cta_lr;
99 uchar insCA[] = {0xDD, 0xCA, 0x00, 0x00, 0x00};
101 write_cmd(cmd, data); // select record
102 if(cta_res[0] != 0x98)
103 { return (-1); }
105 insCA[4] = cta_res[1]; // get len
106 write_cmd(insCA, NULL); // read record
107 if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1]))
108 { return (-1); }
109 return (cta_lr - 2);
112 static uint8_t PairingECMRotation(struct s_reader *reader, const ECM_REQUEST *er, int32_t n)
114 unsigned char cta_res[CTA_RES_LEN] = {0x00};
115 uchar ins26[] = {0xDD, 0x26, 0x00, 0x00, 0x03, 0x10, 0x01, 0x00};
116 uint8_t cnxcurrecm = 0;
118 if(0x0 != reader->rsa_mod[0] && n > 3 &&
119 0x54 == er->ecm[n - 3] &&
120 0x02 == er->ecm[n - 2] &&
121 0x00 == er->ecm[n - 1])
123 cnxcurrecm = 1;
126 if((0 == reader->cnxlastecm) != (0 == cnxcurrecm))
128 if(0 == cnxcurrecm) // not paired
129 { ins26[7] = 0x30; }
130 else
131 { ins26[7] = 0x40; }
133 if(read_record(reader, ins26, ins26 + 5, cta_res) <= 0)
134 { rdr_log(reader, "PairingECMRotation - ERROR"); }
136 reader->cnxlastecm = cnxcurrecm;
137 return cnxcurrecm;
140 static int32_t conax_card_init(struct s_reader *reader, ATR *newatr)
142 unsigned char cta_res[CTA_RES_LEN];
143 int32_t i, j, n;
144 static const uchar ins26[] = {0xDD, 0x26, 0x00, 0x00, 0x03, 0x10, 0x01, 0x40};
145 uchar ins82[] = {0xDD, 0x82, 0x00, 0x00, 0x11, 0x11, 0x0f, 0x01, 0xb0, 0x0f, 0xff, \
146 0xff, 0xfb, 0x00, 0x00, 0x09, 0x04, 0x0b, 0x00, 0xe0, 0x30, 0x2b
149 uchar cardver = 0;
151 get_hist;
152 if((hist_size < 4) || (memcmp(hist, "0B00", 4)))
153 { return ERROR; }
155 reader->caid = 0xB00;
157 if((n = read_record(reader, ins26, ins26 + 5, cta_res)) <= 0) { return ERROR; } // read caid, card-version
159 for(i = 0; i < n; i += cta_res[i + 1] + 2)
160 switch(cta_res[i])
162 case 0x20:
163 cardver = cta_res[i + 2];
164 break;
165 case 0x28:
166 reader->caid = (cta_res[i + 2] << 8) | cta_res[i + 3];
169 // Ins82 command needs to use the correct CAID reported in nano 0x28
170 ins82[17] = (reader->caid >> 8) & 0xFF;
171 ins82[18] = (reader->caid) & 0xFF;
173 if((n = read_record(reader, ins82, ins82 + 5, cta_res)) <= 0) { return ERROR; } // read serial
175 reader->nprov = 0;
177 for(j = 0, i = 2; i < n; i += cta_res[i + 1] + 2)
178 switch(cta_res[i])
180 case 0x23:
181 if(cta_res[i + 5] != 0x00)
183 memcpy(reader->hexserial, &cta_res[i + 3], 6);
185 else
187 memcpy(reader->sa[j], &cta_res[i + 5], 4);
188 j++;
189 reader->nprov++;
191 break;
194 memset(reader->prid, 0x00, sizeof(reader->prid));
196 rdr_log_sensitive(reader, "type: Conax, caid: %04X, serial: {%llu}, hex serial: {%02x%02x%02x%02x}, card: v%d",
197 reader->caid, (unsigned long long) b2ll(6, reader->hexserial), reader->hexserial[2],
198 reader->hexserial[3], reader->hexserial[4], reader->hexserial[5], cardver);
200 rdr_log(reader, "Providers: %d", reader->nprov);
202 for(j = 0; j < reader->nprov; j++)
204 rdr_log(reader, "Provider: %d Provider-Id: %06X", j + 1, b2i(4, reader->prid[j]));
205 rdr_log_sensitive(reader, "Provider: %d SharedAddress: {%08X}", j + 1, b2i(4, reader->sa[j]));
208 return OK;
211 static int32_t conax_send_pin(struct s_reader *reader)
213 def_resp;
214 unsigned char insPIN[] = { 0xDD, 0xC8, 0x00, 0x00, 0x07, 0x1D, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00 }; //Last four are the Pin-Code
215 memcpy(insPIN + 8, reader->pincode, 4);
217 write_cmd(insPIN, insPIN + 5);
218 rdr_log_dbg(reader, D_READER, "Sent pincode to card.");
220 return OK;
223 static int32_t conax_do_ecm(struct s_reader *reader, const ECM_REQUEST *er, struct s_ecm_answer *ea)
225 def_resp;
226 int32_t i, j, n, num_dw = 0, rc = 0;
227 unsigned char insA2[] = { 0xDD, 0xA2, 0x00, 0x00, 0x00 };
228 unsigned char insCA[] = { 0xDD, 0xCA, 0x00, 0x00, 0x00 };
230 unsigned char exp[] = {0x01, 0x00, 0x01};
231 unsigned char buf[256];
233 if((n = check_sct_len(er->ecm, 3)) < 0)
234 { return ERROR; }
236 buf[0] = 0x14;
237 buf[1] = n + 1;
238 if(0x0 != PairingECMRotation(reader, er, n))
239 { buf[2] = 2; } // card will answer with encrypted dw
240 else
241 { buf[2] = 0; }
243 memcpy(buf + 3, er->ecm, n);
244 insA2[4] = n + 3;
246 write_cmd(insA2, buf); // write Header + ECM
248 while((cta_res[cta_lr - 2] == 0x98) && // Antwort
249 ((insCA[4] = cta_res[cta_lr - 1]) > 0) && (insCA[4] != 0xFF))
251 write_cmd(insCA, NULL); //Codeword auslesen
253 if((cta_res[cta_lr - 2] == 0x98) ||
254 ((cta_res[cta_lr - 2] == 0x90)))
256 /*checks if answer is encrypted with RSA algo and decrypts it if needed*/
257 if(0x81 == cta_res[0] && 2 == cta_res[2] >> 5) /*81 XX 5X*/
259 if(0x00 == cta_res[cta_lr - 1])
260 { rc = RSA_CNX(reader, cta_res, reader->rsa_mod, exp, cta_lr, 64u, 3u); }
261 else
262 { rc = -4; } /*card has no right to decode this channel*/
265 if(0 == rc)
266 for(i = 0; i < cta_lr - 2 && num_dw < 2; i += cta_res[i + 1] + 2)
268 switch(cta_res[i])
270 case 0x25:
271 if((cta_res[i + 1] >= 0xD) && !((n = cta_res[i + 4]) & 0xFE))
273 rc |= (1 << n);
274 memcpy(ea->cw + (n << 3), cta_res + i + 7, 8);
275 ++num_dw;
277 break;
278 case 0x31:
279 if((cta_res[i + 1] == 0x02 && cta_res[i + 2] == 0x00 && cta_res[i + 3] == 0x00) || \
280 (cta_res[i + 1] == 0x02 && cta_res[i + 2] == 0x40 && cta_res[i + 3] == 0x00))
281 { break; }
282 else if(strcmp(reader->pincode, "none"))
284 conax_send_pin(reader);
285 write_cmd(insA2, buf); // write Header + ECM
287 while((cta_res[cta_lr - 2] == 0x98) && // Antwort
288 ((insCA[4] = cta_res[cta_lr - 1]) > 0) && (insCA[4] != 0xFF))
290 write_cmd(insCA, NULL); //Codeword auslesen
292 if((cta_res[cta_lr - 2] == 0x98) ||
293 ((cta_res[cta_lr - 2] == 0x90) && (!cta_res[cta_lr - 1])))
295 for(j = 0; j < cta_lr - 2; j += cta_res[j + 1] + 2)
296 if((cta_res[j] == 0x25) && // access: is cw
297 (cta_res[j + 1] >= 0xD) && // 0xD: 5 header + 8 cw
298 !((n = cta_res[j + 4]) & 0xFE)) // cw idx must be 0 or 1
300 rc |= (1 << n);
301 memcpy(ea->cw + (n << 3), cta_res + j + 7, 8);
302 ++num_dw;
307 break;
313 switch(rc)
315 case -1:
316 rdr_log(reader, "conax decode ECM problem - RSA key is probably faulty");
317 break;
318 case -2:
319 rdr_log(reader, "conax RSA pairing - wrong size of data");
320 break;
321 case -3:
322 rdr_log(reader, "conax RSA pairing- wrong size of data for second round");
323 case -4:
324 rdr_log(reader, "card has no right to decode this channel");
325 break;
328 /* answer 9011 - conax smart card need reset */
329 if(2 <= cta_lr && 0x90 == cta_res[cta_lr - 2] &&
330 0x11 == cta_res[cta_lr - 1])
332 rdr_log(reader, "conax card hangs - reset is required");
333 reader->card_status = UNKNOWN;
336 if(rc == 3)
337 { return OK; }
338 else
339 { return ERROR; }
342 static int32_t conax_get_emm_type(EMM_PACKET *ep, struct s_reader *rdr)
344 int32_t i, ok = 0;
345 char tmp_dbg[17];
347 rdr_log_dbg(rdr, D_EMM, "Entered conax_get_emm_type ep->emm[2]=%02x", ep->emm[2]);
349 for(i = 0; i < rdr->nprov; i++)
351 ok = (!memcmp(&ep->emm[6], rdr->sa[i], 4));
352 if(ok) { break; }
355 if(ok)
357 ep->type = SHARED;
358 memset(ep->hexserial, 0, 8);
359 memcpy(ep->hexserial, &ep->emm[6], 4);
360 rdr_log_dbg_sensitive(rdr, D_EMM, "SHARED, ep->hexserial = {%s}", cs_hexdump(1, ep->hexserial, 8, tmp_dbg, sizeof(tmp_dbg)));
361 return 1;
363 else
365 if(!memcmp(&ep->emm[6], rdr->hexserial + 2, 4))
367 ep->type = UNIQUE;
368 memset(ep->hexserial, 0, 8);
369 memcpy(ep->hexserial + 2, &ep->emm[6], 4);
370 rdr_log_dbg_sensitive(rdr, D_EMM, "UNIQUE, ep->hexserial = {%s}", cs_hexdump(1, ep->hexserial, 8, tmp_dbg, sizeof(tmp_dbg)));
371 return 1;
373 else
375 ep->type = GLOBAL;
376 rdr_log_dbg(rdr, D_EMM, "GLOBAL");
377 memset(ep->hexserial, 0, 8);
378 return 1;
383 static int32_t conax_get_emm_filter(struct s_reader *rdr, struct s_csystem_emm_filter **emm_filters, unsigned int *filter_count)
385 if(*emm_filters == NULL)
387 const unsigned int max_filter_count = 2 + rdr->nprov;
388 if(!cs_malloc(emm_filters, max_filter_count * sizeof(struct s_csystem_emm_filter)))
389 { return ERROR; }
391 struct s_csystem_emm_filter *filters = *emm_filters;
392 *filter_count = 0;
394 int idx = 0, prov;
396 filters[idx].type = EMM_GLOBAL;
397 filters[idx].enabled = 0; // FIXME: dont see any conax global EMM yet
398 filters[idx].filter[0] = 0x82;
399 filters[idx].mask[0] = 0xFF;
400 filters[idx].filter[8] = 0x70;
401 filters[idx].mask[8] = 0xFF;
402 idx++;
404 for(prov = 0; prov < rdr->nprov; prov++)
406 filters[idx].type = EMM_SHARED;
407 filters[idx].enabled = 1;
408 filters[idx].filter[0] = 0x82;
409 filters[idx].mask[0] = 0xFF;
410 memcpy(&filters[idx].filter[4], rdr->sa[prov], 4);
411 memset(&filters[idx].mask[4], 0xFF, 4);
412 idx++;
415 filters[idx].type = EMM_UNIQUE;
416 filters[idx].enabled = 1;
417 filters[idx].filter[0] = 0x82;
418 filters[idx].mask[0] = 0xFF;
419 memcpy(&filters[idx].filter[4], rdr->hexserial + 2, 4);
420 memset(&filters[idx].mask[4], 0xFF, 4);
421 idx++;
423 *filter_count = idx;
426 return OK;
429 static int32_t conax_do_emm(struct s_reader *reader, EMM_PACKET *ep)
431 def_resp;
432 unsigned char insCA[] = { 0xDD, 0xCA, 0x00, 0x00, 0x00 };
433 unsigned char insEMM[] = { 0xDD, 0x84, 0x00, 0x00, 0x00 };
434 unsigned char buf[255];
435 int32_t rc = 0;
437 const int32_t l = ep->emm[2];
439 insEMM[4] = l + 5;
440 buf[0] = 0x12;
441 buf[1] = l + 3;
442 memcpy(buf + 2, ep->emm, buf[1]);
443 write_cmd(insEMM, buf);
445 if(cta_res[0] == 0x98)
447 insCA[4] = cta_res[1];
448 write_cmd(insCA, NULL);
451 rc = ((cta_res[0] == 0x90) && (cta_res[1] == 0x00));
453 if(rc)
454 { return OK; }
455 else
456 { return ERROR; }
459 static int32_t conax_card_info(struct s_reader *reader)
461 def_resp;
462 int32_t type, i, j, k = 0, n = 0, l;
463 uint16_t provid = 0;
464 char provname[32], pdate[32], chid[32];
465 static const uchar insC6[] = {0xDD, 0xC6, 0x00, 0x00, 0x03, 0x1C, 0x01, 0x00};
466 static const uchar ins26[] = {0xDD, 0x26, 0x00, 0x00, 0x03, 0x1C, 0x01, 0x01};
467 uchar insCA[] = {0xDD, 0xCA, 0x00, 0x00, 0x00};
468 char *txt[] = { "Package", "PPV-Event" };
469 static const uchar *cmd[] = { insC6, ins26 };
470 time_t start_t = 0, end_t = 0;
471 uint32_t cxclass = 0;
473 cs_clear_entitlement(reader); // reset the entitlements
475 for(type = 0; type < 2; type++)
477 n = 0;
478 write_cmd(cmd[type], cmd[type] + 5);
479 while(cta_res[cta_lr - 2] == 0x98)
481 insCA[4] = cta_res[cta_lr - 1]; // get len
482 write_cmd(insCA, NULL); // read
483 if((cta_res[cta_lr - 2] == 0x90) || (cta_res[cta_lr - 2] == 0x98))
485 for(j = 0; j < cta_lr - 2; j += cta_res[j + 1] + 2)
487 provid = (cta_res[j + 2 + type] << 8) | cta_res[j + 3 + type];
488 chid[0] = '\0';
489 for(k = 0, i = j + 4 + type; (i < j + cta_res[j + 1]); i += cta_res[i + 1] + 2)
491 switch(cta_res[i])
493 case 0x01:
494 l = (cta_res[i + 1] < (sizeof(provname) - 1)) ? cta_res[i + 1] : sizeof(provname) - 1;
495 memcpy(provname, cta_res + i + 2, l);
496 provname[l] = '\0';
497 break;
498 case 0x30:
499 if(k > 1)
501 rdr_log(reader, "%s: %d, id: %04X%s, date: %s - %s, name: %s", txt[type], ++n, provid, chid, pdate, pdate + 16, trim(provname));
503 // add entitlements to list
504 cs_add_entitlement(reader, reader->caid, b2ll(4, reader->prid[0]), provid, cxclass, start_t, end_t, type + 1, 1);
506 k = 0;
507 chid[0] = '\0';
509 if(k == 0) { start_t = chid_date(cta_res + i + 2, pdate, 15); }
510 else { end_t = chid_date(cta_res + i + 2, pdate + 16, 15) /* add 23:59:59 here: */ + 0x1517F; }
511 ++k;
512 break;
513 case 0x20: // Provider classes
514 case 0x90: // (?) not sure what this is, saw it once in log
515 snprintf(chid, sizeof(chid), ", classes: %02X%02X%02X%02X", cta_res[i + 2], cta_res[i + 3], cta_res[i + 4] , cta_res[i + 5]);
516 cxclass = b2ll(4, &cta_res[i + 2]);
517 break;
520 rdr_log(reader, "%s: %d, id: %04X%s, date: %s - %s, name: %s", txt[type], ++n, provid, chid, pdate, pdate + 16, trim(provname));
522 // add entitlements to list
523 cs_add_entitlement(reader, reader->caid, b2ll(4, reader->prid[0]), provid, cxclass, start_t, end_t, type + 1, 1);
528 rdr_log(reader, "ready for requests");
529 return OK;
532 const struct s_cardsystem reader_conax =
534 .desc = "conax",
535 .caids = (uint16_t[]){ 0x0B, 0 },
536 .do_emm = conax_do_emm,
537 .do_ecm = conax_do_ecm,
538 .card_info = conax_card_info,
539 .card_init = conax_card_init,
540 .get_emm_type = conax_get_emm_type,
541 .get_emm_filter = conax_get_emm_filter,
544 #endif