[gbx] - more generalized routing info in cw msg
[oscam.git] / reader-videoguard2.c
blob894a43fa47fafc2eff3ab19a02b71890ccdb261d
1 #include "globals.h"
2 #ifdef READER_VIDEOGUARD
3 #include "cscrypt/md5.h"
4 #include "cscrypt/des.h"
5 #include "oscam-work.h"
6 #include "reader-common.h"
7 #include "reader-videoguard-common.h"
10 static void do_post_dw_hash(struct s_reader *reader, uint8_t *cw, const uint8_t *ecm_header_data)
12 int32_t i, ecmi, ecm_header_count;
13 uint8_t buffer[0x85]; // original 0x80 but with 0x7D mask applied +8 bytes cw it was still to small
14 uint8_t md5tmp[MD5_DIGEST_LENGTH];
16 static const uint16_t Hash3[] = { 0x0123, 0x4567, 0x89AB, 0xCDEF, 0xF861, 0xCB52 };
17 static const uint8_t Hash4[] = { 0x0B, 0x04, 0x07, 0x08, 0x05, 0x09, 0x0B, 0x0A,
18 0x07, 0x02, 0x0A, 0x05, 0x04, 0x08, 0x0D, 0x0F };
20 static const uint16_t NdTabB001[0x15][0x20] =
23 0xEAF1, 0x0237, 0x29D0, 0xBAD2, 0xE9D3, 0x8BAE, 0x2D6D, 0xCD1B,
24 0x538D, 0xDE6B, 0xA634, 0xF81A, 0x18B5, 0x5087, 0x14EA, 0x672E,
25 0xF0FC, 0x055E, 0x62E5, 0xB78F, 0x5D09, 0x0003, 0xE4E8, 0x2DCE,
26 0x6BE0, 0xAC4E, 0xF485, 0x6967, 0xF28C, 0x97A0, 0x01EF, 0x0100
29 0xC539, 0xF5B9, 0x9099, 0x013A, 0xD4B9, 0x6AB5, 0xEA67, 0x7EB4,
30 0x6C30, 0x4BF0, 0xB810, 0xB0B5, 0xB76D, 0xA751, 0x1AE7, 0x14CA,
31 0x4F4F, 0x1586, 0x2608, 0x10B1, 0xE7E1, 0x48BE, 0x7DDD, 0x5ECB,
32 0xCFBF, 0x323B, 0x8B31, 0xB131, 0x0F1A, 0x664B, 0x0140, 0x0100
35 0x3C7D, 0xBDC4, 0xFEC7, 0x26A6, 0xB0A0, 0x6E55, 0xF710, 0xF9BF,
36 0x0023, 0xE81F, 0x41CA, 0xBE32, 0xB461, 0xE92D, 0xF1AF, 0x409F,
37 0xFC85, 0xFE5B, 0x7FCE, 0x17F5, 0x01AB, 0x4A46, 0xEB05, 0xA251,
38 0xDC6F, 0xF0C0, 0x10F0, 0x1D51, 0xEFAA, 0xE9BF, 0x0100, 0x0100
41 0x1819, 0x0CAA, 0x9067, 0x607A, 0x7576, 0x1CBC, 0xE51D, 0xBF77,
42 0x7EC6, 0x839E, 0xB695, 0xF096, 0xDC10, 0xCB69, 0x4654, 0x8E68,
43 0xD62D, 0x4F1A, 0x4227, 0x92AC, 0x9064, 0x6BD1, 0x1E75, 0x2747,
44 0x00DA, 0xA6A6, 0x6CF1, 0xD151, 0xBE56, 0x3E33, 0x0128, 0x0100
47 0x4091, 0x09ED, 0xD494, 0x6054, 0x1869, 0x71D5, 0xB572, 0x7BF1,
48 0xE925, 0xEE2D, 0xEEDE, 0xA13C, 0x6613, 0x9BAB, 0x122D, 0x7AE4,
49 0x5268, 0xE6C9, 0x50CB, 0x79A1, 0xF212, 0xA062, 0x6B48, 0x70B3,
50 0xF6B0, 0x06D5, 0xF8AB, 0xECF5, 0x6255, 0xEDD8, 0x79D2, 0x290A
53 0xD3CF, 0x014E, 0xACB3, 0x8F6B, 0x0F2C, 0xA5D8, 0xE8E0, 0x863D,
54 0x80D5, 0x5705, 0x658A, 0x8BC2, 0xEE46, 0xD3AE, 0x0199, 0x0100,
55 0x4A35, 0xABE4, 0xF976, 0x935A, 0xA8A5, 0xBAE9, 0x24D0, 0x71AA,
56 0xB3FE, 0x095E, 0xAB06, 0x4CD5, 0x2F0D, 0x1ACB, 0x59F3, 0x4C50
59 0xFD27, 0x0F8E, 0x191A, 0xEEE7, 0x2F49, 0x3A05, 0x3267, 0x4F88,
60 0x38AE, 0xFCE9, 0x9476, 0x18C6, 0xF961, 0x4EF0, 0x39D0, 0x42E6,
61 0xB747, 0xE625, 0xB68E, 0x5100, 0xF92A, 0x86FE, 0xE79B, 0xEE91,
62 0x21D5, 0x4C3C, 0x683D, 0x5AD1, 0x1B49, 0xF407, 0x0194, 0x0100
65 0x4BF9, 0xDC0D, 0x9478, 0x5174, 0xCB4A, 0x8A89, 0x4D6A, 0xFED8,
66 0xF123, 0xA8CD, 0xEEE7, 0xA6D1, 0xB763, 0xF5E2, 0xE085, 0x01EF,
67 0xE466, 0x9FA3, 0x2F68, 0x2190, 0x423F, 0x287F, 0x7F3F, 0x09F6,
68 0x2111, 0xA963, 0xD0BB, 0x674A, 0xBA72, 0x45F9, 0xF186, 0xB8F5
71 0x0010, 0xD1B9, 0xB164, 0x9E87, 0x1F49, 0x6950, 0x2DBF, 0x38D3,
72 0x2EB0, 0x3E8E, 0x91E6, 0xF688, 0x7E41, 0x566E, 0x01B0, 0x0100,
73 0x24A1, 0x73D8, 0xA0C3, 0xF71B, 0xA0A5, 0x2A06, 0xBA46, 0xFEC3,
74 0xDD4C, 0x52CC, 0xF9BC, 0x3B7E, 0x3812, 0x0666, 0xB74B, 0x40F8
77 0x28F2, 0x7C81, 0xFC92, 0x6FBD, 0x53D6, 0x72A3, 0xBBDF, 0xB6FC,
78 0x9CE5, 0x2331, 0xD4F6, 0xC5BB, 0xE8BB, 0x6676, 0x02D9, 0x2F0E,
79 0xD009, 0xD136, 0xCD09, 0x7551, 0x1826, 0x9D9B, 0x63EA, 0xFC63,
80 0x68CD, 0x3672, 0xCB95, 0xD28E, 0xF1CD, 0x20CA, 0x014C, 0x0100
83 0xE539, 0x55B7, 0x989D, 0x21C4, 0x463A, 0xE68F, 0xF8B5, 0xE5C5,
84 0x662B, 0x35BF, 0x3C50, 0x0131, 0xF4BF, 0x38B2, 0x41BC, 0xB829,
85 0x02B7, 0x6B8F, 0xA25C, 0xAFD2, 0xD84A, 0x2243, 0x53EB, 0xC6C9,
86 0x2E14, 0x181F, 0x8F96, 0xDF0E, 0x0D4C, 0x30F6, 0xFFE1, 0x9DDA
89 0x30B6, 0x777E, 0xDA3D, 0xAF77, 0x205E, 0xC90B, 0x856B, 0xB451,
90 0x3BCC, 0x76C2, 0x8ACF, 0xDCB1, 0xA5E5, 0xDD64, 0x0197, 0x0100,
91 0xE751, 0xB661, 0x0404, 0xDB4A, 0xE9DD, 0xA400, 0xAF26, 0x3F5E,
92 0x904B, 0xA924, 0x09E0, 0xE72B, 0x825B, 0x2C50, 0x6FD0, 0x0D52
95 0x2730, 0xC2BA, 0x9E44, 0x5815, 0xFC47, 0xB21D, 0x67B8, 0xF8B9,
96 0x047D, 0xB0AF, 0x9F14, 0x741B, 0x4668, 0xBE54, 0xDE16, 0xDB14,
97 0x7CB7, 0xF2B8, 0x0683, 0x762C, 0x09A0, 0x9507, 0x7F92, 0x022C,
98 0xBA6A, 0x7D52, 0x0AF4, 0x1BC3, 0xB46A, 0xC4FD, 0x01C2, 0x0100
101 0x7611, 0x66F3, 0xEE87, 0xEDD3, 0xC559, 0xEFD4, 0xDC59, 0xF86B,
102 0x6D1C, 0x1C85, 0x9BB1, 0x3373, 0x763F, 0x4EBE, 0x1BF3, 0x99B5,
103 0xD721, 0x978F, 0xCF5C, 0xAC51, 0x0984, 0x7462, 0x8F0C, 0x2817,
104 0x4AD9, 0xFD41, 0x6678, 0x7C85, 0xD330, 0xC9F8, 0x1D9A, 0xC622
107 0x5AE4, 0xE16A, 0x60F6, 0xFD45, 0x668C, 0x29D6, 0x0285, 0x6B92,
108 0x92C2, 0x21DE, 0x45E0, 0xEF3D, 0x8B0D, 0x02CD, 0x0198, 0x0100,
109 0x9E6D, 0x4D38, 0xDEF9, 0xE6F2, 0xF72E, 0xB313, 0x14F2, 0x390A,
110 0x2D67, 0xC71E, 0xCB69, 0x7F66, 0xD3CF, 0x7F8A, 0x81D9, 0x9DDE
113 0x85E3, 0x8F29, 0x36EB, 0xC968, 0x3696, 0x59F6, 0x7832, 0xA78B,
114 0xA1D8, 0xF5CF, 0xAB64, 0x646D, 0x7A2A, 0xBAF8, 0xAA87, 0x41C7,
115 0x5120, 0xDE78, 0x738D, 0xDC1A, 0x268D, 0x5DF8, 0xED69, 0x1C8A,
116 0xBC85, 0x3DCD, 0xAE30, 0x0F8D, 0xEC89, 0x3ABD, 0x0166, 0x0100
119 0xB8BD, 0x643B, 0x748E, 0xBD63, 0xEC6F, 0xE23A, 0x9493, 0xDD76,
120 0x0A62, 0x774F, 0xCD68, 0xA67A, 0x9A23, 0xC8A8, 0xBDE5, 0x9D1B,
121 0x2B86, 0x8B36, 0x5428, 0x1DFB, 0xCD1D, 0x0713, 0x29C2, 0x8E8E,
122 0x5207, 0xA13F, 0x6005, 0x4F5E, 0x52E0, 0xE7C8, 0x6D1C, 0x3E34
125 0x581D, 0x2BFA, 0x5E1D, 0xA891, 0x1069, 0x1DA4, 0x39A0, 0xBE45,
126 0x5B9A, 0x7333, 0x6F3E, 0x8637, 0xA550, 0xC9E9, 0x5C6C, 0x42BA,
127 0xA712, 0xC3EA, 0x3808, 0x0910, 0xAA4D, 0x5B25, 0xABCD, 0xE680,
128 0x96AD, 0x2CEC, 0x8EBB, 0xA47D, 0x1690, 0xE8FB, 0x01C8, 0x0100
131 0x73B9, 0x82BC, 0x9EBC, 0xB130, 0x0DA5, 0x8617, 0x9F7B, 0x9766,
132 0x205D, 0x752D, 0xB05C, 0x2A17, 0xA75C, 0x18EF, 0x8339, 0xFD34,
133 0x8DA2, 0x7970, 0xD0B4, 0x70F1, 0x3765, 0x7380, 0x7CAF, 0x570E,
134 0x6440, 0xBC44, 0x0743, 0x2D02, 0x0419, 0xA240, 0x2113, 0x1AD4
137 0x1EB5, 0xBBFF, 0x39B1, 0x3209, 0x705F, 0x15F4, 0xD7AD, 0x340B,
138 0xC2A6, 0x25CA, 0xF412, 0x9570, 0x0F4F, 0xE4D5, 0x1614, 0xE464,
139 0x911A, 0x0F0E, 0x07DA, 0xA929, 0x2379, 0xD988, 0x0AA6, 0x3B57,
140 0xBF63, 0x71FB, 0x72D5, 0x26CE, 0xB0AF, 0xCF45, 0x011B, 0x0100
143 0x9999, 0x98FE, 0xA108, 0x6588, 0xF90B, 0x4554, 0xFF38, 0x4642,
144 0x8F5F, 0x6CC3, 0x4E8E, 0xFF7E, 0x64C2, 0x50CA, 0x0E7F, 0xAD7D,
145 0x6AAB, 0x33C1, 0xE1F4, 0x6165, 0x7894, 0x83B9, 0x0A0C, 0x38AF,
146 0x5803, 0x18C0, 0xFA36, 0x592C, 0x4548, 0xABB8, 0x1527, 0xAEE9
150 //ecm_header_data = 01 03 b0 01 01
151 if(!cw_is_valid(cw)) // if cw is all zero, keep it that way
153 return;
156 ecm_header_count = ecm_header_data[0];
157 for(i = 0, ecmi = 1; i < ecm_header_count; i++)
159 if(ecm_header_data[ecmi + 1] != 0xb0)
161 ecmi += ecm_header_data[ecmi] + 1;
163 else
165 switch(ecm_header_data[ecmi + 2])
167 case 1: // b0 01
169 uint16_t hk[8], r, j, m = 0;
170 for(r = 0; r < 6; r++)
172 hk[2 + r] = Hash3[r];
175 for(r = 0; r < 2; r++)
177 for(j = 0; j < 0x48; j += 2)
179 if(r)
181 hk[0] = ((hk[3] & hk[5]) | ((~hk[5]) & hk[4]));
183 else
185 hk[0] = ((hk[3] & hk[4]) | ((~hk[3]) & hk[5]));
188 if(j < 8)
190 hk[0] = (hk[0] + ((cw[j + 1] << 8) | cw[j]));
193 if(j == 8)
195 hk[0] = (hk[0] + 0x80);
198 hk[0] = (hk[0] + hk[2] + (0xFF & NdTabB001[ecm_header_data[ecmi + 3]][m >> 1] >> ((m & 1) << 3)));
199 hk[1] = hk[2];
200 hk[2] = hk[3];
201 hk[3] = hk[4];
202 hk[4] = hk[5];
203 hk[5] = hk[6];
204 hk[6] = hk[7];
205 hk[7] = hk[2] + (((hk[0] << Hash4[m & 0xF]) | (hk[0] >> (0x10 - Hash4[m & 0xF]))));
206 m = (m + 1) & 0x3F;
210 for(r = 0; r < 6; r++)
212 hk[2 + r] += Hash3[r];
215 for(r = 0; r < 7; r++)
217 cw[r] = hk[2 + (r >> 1)] >> ((r & 1) << 3);
220 cw[3] = (cw[0] + cw[1] + cw[2]) & 0xFF;
221 cw[7] = (cw[4] + cw[5] + cw[6]) & 0xFF;
222 rdr_log_dump_dbg(reader, D_READER, cw, 8, "Postprocessed Case 1 DW:");
223 break;
226 case 3:
228 memset(buffer, 0, sizeof(buffer));
229 memcpy(buffer, cw, 8);
230 memcpy(buffer + 8, &ecm_header_data[ecmi + 3], ecm_header_data[ecmi] & 0x7D);
231 MD5(buffer, 8 + (ecm_header_data[ecmi] & 0x7D), md5tmp);
232 memcpy(cw, md5tmp, 8);
233 rdr_log_dump_dbg(reader, D_READER, cw, 8, "Postprocessed Case 3 DW:");
234 break;
237 case 2:
239 // Method 2 left out
240 //memcpy(DW_OUTPUT, DW_INPUT, 8);
241 break;
248 static void vg2_read_tiers(struct s_reader *reader)
250 uint8_t cta_res[CTA_RES_LEN];
251 struct videoguard_data *csystem_data = reader->csystem_data;
253 if(reader->readtiers == 1)
255 uint8_t ins707f[5] = { 0xD1, 0x70, 0x00, 0x7f, 0x02 };
256 if(do_cmd(reader, ins707f, NULL, NULL, cta_res) < 0)
258 rdr_log(reader, "classD1 ins707f: failed to get number of classes supported");
260 else
262 cs_clear_entitlement(reader);
263 rdr_log(reader, "------------------------------------------------------------------");
264 rdr_log(reader, "|- class -|-- tier --|----- valid to ------|--- package name ----|");
265 rdr_log(reader, "+---------+----------+---------------------+---------------------+");
267 if((reader->VgFuse & 5) == 0)
269 rdr_log(reader, "|------- This card is not active, so no package available! ------|");
272 uint32_t TierClass, ClassSupported;
273 ClassSupported = cta_res[1];
274 uint8_t ins70[5] = { 0xD1, 0x70, 0x00, 0x00, 0x00 };
276 for(TierClass = 0; TierClass < ClassSupported; TierClass++)
278 ins70[2] = TierClass;
279 if(do_cmd(reader, ins70, NULL, NULL, cta_res) < 0)
281 rdr_log(reader, "classD1 ins70: failed to get tiers for class %02X", TierClass);
283 else
285 char tiername[83];
286 uint32_t word;
287 uint32_t bitnum;
288 uint32_t tier_id;
289 struct tm timeinfo;
290 memset(&timeinfo, 0, sizeof(struct tm));
291 time_t start_t = 0, end_t;
293 if(cta_res[1] > 0x23)
295 rev_date_calc_tm(&cta_res[38], &timeinfo, csystem_data->card_baseyear);
296 start_t = mktime(&timeinfo);
299 rev_date_calc_tm(&cta_res[34], &timeinfo, csystem_data->card_baseyear);
300 end_t = mktime(&timeinfo);
302 for(word = 0; word < 32; word += 2)
304 for (bitnum = 0; bitnum < 8; bitnum++)
306 if((cta_res[word + 2] >> bitnum) & 1)
308 tier_id = 0;
309 tier_id = ((TierClass << 8) + (word << 3) + bitnum);
310 cs_add_entitlement(reader, reader->caid, b2ll(4, reader->prid[0]), tier_id, TierClass, start_t, end_t, 4, 1);
311 rdr_log(reader, "|-- %02x ---|-- %04x --| %04d/%02d/%02d-%02d:%02d:%02d | %s",
312 TierClass,
313 tier_id,
314 timeinfo.tm_year + 1900,
315 timeinfo.tm_mon + 1,
316 timeinfo.tm_mday,
317 timeinfo.tm_hour,
318 timeinfo.tm_min,
319 timeinfo.tm_sec,
320 get_tiername(tier_id, reader->caid, tiername));
323 if((cta_res[word + 1 + 2] >> bitnum) & 1)
325 tier_id = 0;
326 tier_id = ((TierClass << 8) + (word << 3) + bitnum + 8);
327 cs_add_entitlement(reader, reader->caid, b2ll(4, reader->prid[0]), tier_id, TierClass, start_t, end_t, 4, 1);
328 rdr_log(reader, "|-- %02x ---|-- %04x --| %04d/%02d/%02d-%02d:%02d:%02d | %s",
329 TierClass,
330 tier_id,
331 timeinfo.tm_year + 1900,
332 timeinfo.tm_mon + 1,
333 timeinfo.tm_mday,
334 timeinfo.tm_hour,
335 timeinfo.tm_min,
336 timeinfo.tm_sec,
337 get_tiername(tier_id, reader->caid, tiername));
344 rdr_log(reader, "------------------------------------------------------from-ins70--");
346 else if(reader->readtiers == 2)
348 int32_t l;
349 // ins2a is not needed and causes an error on some cards eg Sky Italy 09CD
350 // check if ins2a is in command table before running it
352 static const uint8_t ins2a[5] = { 0xD1, 0x2a, 0x00, 0x00, 0x00 };
353 if(cmd_exists(reader, ins2a))
355 l = do_cmd(reader, ins2a, NULL, NULL, cta_res);
356 if(l < 0 || !status_ok(cta_res + l))
358 rdr_log(reader, "classD1 ins2a: failed");
359 return;
363 static const uint8_t ins76007f[5] = { 0xD1, 0x76, 0x00, 0x7f, 0x02 };
364 l = do_cmd(reader, ins76007f, NULL, NULL, cta_res);
365 if(l < 0 || !status_ok(cta_res + 2))
367 rdr_log(reader, "classD1 ins76007f: failed");
368 return;
370 int32_t num = cta_res[1];
372 int32_t i;
373 uint8_t ins76[5] = { 0xD1, 0x76, 0x00, 0x00, 0x00 };
375 // some cards start real tiers info in middle of tier info
376 // and have blank tiers between old tiers and real tiers eg 09AC
377 int32_t starttier = csystem_data->card_tierstart;
378 bool stopemptytier = 1;
379 if(!starttier)
381 stopemptytier = 0;
384 // check to see if specified start tier is blank and if blank, start at 0 and ignore blank tiers
385 ins76[2] = starttier;
386 l = do_cmd(reader, ins76, NULL, NULL, cta_res);
387 if(l < 0 || !status_ok(cta_res + l))
389 return;
392 if(cta_res[2] == 0 && cta_res[3] == 0)
394 stopemptytier = 0;
395 starttier = 0;
398 cs_clear_entitlement(reader); // reset the entitlements
399 rdr_log(reader, "------------------------------------------------------------------");
400 rdr_log(reader, "|- class -|-- tier --|----- valid to ------|--- package name ----|");
401 rdr_log(reader, "+---------+----------+---------------------+---------------------+");
402 if((reader->VgFuse&5) == 0)
404 rdr_log(reader, "|------- This card is not active, so no package available! ------|");
407 for(i = starttier; i < num; i++)
409 ins76[2] = i;
410 l = do_cmd(reader, ins76, NULL, NULL, cta_res);
412 if(l < 0 || !status_ok(cta_res + l))
414 return;
417 if(cta_res[2] == 0 && cta_res[3] == 0 && stopemptytier)
419 return;
422 if(cta_res[2] != 0 || cta_res[3] != 0)
424 char tiername[83];
425 uint16_t tier_id = (cta_res[2] << 8) | cta_res[3];
426 // add entitlements to list
427 struct tm timeinfo;
428 memset(&timeinfo, 0, sizeof(struct tm));
429 rev_date_calc_tm(&cta_res[4], &timeinfo, csystem_data->card_baseyear);
430 cs_add_entitlement(reader, reader->caid, b2ll(4, reader->prid[0]), tier_id, 0, 0, mktime(&timeinfo), 4, 1);
432 if(!stopemptytier)
434 rdr_log_dbg(reader, D_READER, "tier: %04x, tier-number: 0x%02x", tier_id, i);
436 rdr_log(reader, "|-- %02x ---|-- %04x --| %04d/%02d/%02d-%02d:%02d:%02d | %s",
437 cta_res[2],
438 tier_id,
439 timeinfo.tm_year + 1900,
440 timeinfo.tm_mon + 1,
441 timeinfo.tm_mday,
442 timeinfo.tm_hour,
443 timeinfo.tm_min,
444 timeinfo.tm_sec,
445 get_tiername(tier_id, reader->caid, tiername));
448 rdr_log(reader, "------------------------------------------------------from-ins76--");
450 else if(reader->readtiers == 0)
452 rdr_log(reader, "------------------------------------------------------------------");
453 rdr_log(reader, "|--- The reading of the tiers is disabled by the configuration --|");
454 rdr_log(reader, "------------------------------------------------------------------");
458 void videoguard2_poll_status(struct s_reader *reader)
460 const time_t poll_interval = 12; // less is better
461 time_t now = time(0);
462 int32_t i;
464 if(now >= reader->last_poll + poll_interval)
466 static const uint8_t ins5C[5] = { 0xD1, 0x5C, 0x00, 0x00, 0x04 };
467 uint8_t cta_res[CTA_RES_LEN];
468 int32_t l;
469 l = do_cmd(reader, ins5C, NULL, NULL, cta_res);
471 if(l < 0 || !status_ok(cta_res + l))
473 rdr_log(reader, "classD1 ins5C: failed");
475 else
477 switch (cta_res[1])
479 case 0x14: // loc_43C250
481 static const uint8_t ins4Ca[5] = { 0xD1, 0x4C, 0x00, 0x00, 0x00 };
482 l = do_cmd(reader, ins4Ca, reader->payload4C, NULL, cta_res);
484 if(l < 0 || !status_ok(cta_res))
486 rdr_log(reader, "classD1 ins4Ca: failed");
489 if(reader->ins7E[0x1A])
491 static const uint8_t ins7E[5] = { 0xD1, 0x7E, 0x10, 0x00, 0x1A };
492 l = do_cmd(reader, ins7E, reader->ins7E, NULL, cta_res);
494 if(l < 0 || !status_ok(cta_res))
496 rdr_log(reader, "classD1 ins7E: failed");
500 if(reader->ins2e06[4])
502 static const uint8_t ins2e06[5] = { 0xD1, 0x2E, 0x06, 0x00, 0x04 };
503 l = do_cmd(reader, ins2e06, reader->ins2e06, NULL, cta_res);
504 if(l < 0 || !status_ok(cta_res))
506 rdr_log(reader, "classD1 ins2E: failed");
510 static const uint8_t ins58a[5] = { 0xD1, 0x58, 0x00, 0x00, 0x00 };
511 if((do_cmd(reader, ins58a, NULL, NULL, cta_res) < 0))
513 rdr_log(reader, "classD1 ins58: failed");
516 reader->VgFuse = cta_res[2];
517 static const uint8_t ins7403a[5] = { 0xD1, 0x74, 0x03, 0x00, 0x00 };
519 if((do_cmd(reader, ins7403a, NULL, NULL, cta_res) < 0))
521 rdr_log(reader, "classD1 ins7403a: failed");
523 else
525 if(((cta_res[2] >> 5) & 1))
527 static const uint8_t ins7423[5] = { 0xD3, 0x74, 0x23, 0x00, 0x00 };
528 if(do_cmd(reader, ins7423, NULL, NULL, cta_res) < 0)
530 rdr_log(reader, "classD1 ins7423: failed");
534 break;
537 case 0xB: // .text:000000000043C050
539 uint8_t ins5E[5] = { 0xD1,0x5E,0x00,0x00,0x00 };
540 ins5E[2] = cta_res[2];
541 ins5E[3] = cta_res[1];
542 ins5E[4] = cta_res[3];
543 l = do_cmd(reader, ins5E, NULL, NULL, cta_res);
545 if(l < 0 || !status_ok(cta_res + l))
547 rdr_log(reader, "Ins5E: failed");
550 uint8_t ins78[5] = { 0xD1, 0x78, 0x00, 0x00, 0x18 };
551 ins78[2] = cta_res[0];
552 l = do_cmd(reader, ins78, NULL, NULL, cta_res);
554 if(l < 0 || !status_ok(cta_res + l))
556 rdr_log(reader, "classD1 ins78: failed");
559 uint8_t ins32[5] = { 0xD1, 0x32, 0x00, 0x00, 0x01 };
560 const uint8_t payload32[1] = { 0x25 };
561 l = do_cmd(reader, ins32, payload32, NULL, cta_res);
563 if(l < 0 || !status_ok(cta_res + l))
565 rdr_log(reader, "classD1 ins32: failed");
567 break;
570 case 0x0C: // loc_43C13F
572 uint8_t ins5E[5] = { 0xD1,0x5E,0x00,0x00,0x00 };
573 ins5E[2] = cta_res[2];
574 ins5E[3] = cta_res[1];
575 ins5E[4] = cta_res[3];
576 l = do_cmd(reader, ins5E, NULL, NULL, cta_res);
578 if(l < 0 || !status_ok(cta_res + l))
580 rdr_log(reader, "Ins5E: failed");
582 else
584 uint8_t ins36[5] = { 0xD1, 0x36, 0x00, 0x00, 0x00 };
585 ins36[4] = cta_res[1];
587 for (i = 0; i <= cta_res[0]; i++)
589 ins36[3] = i;
590 l = do_cmd(reader, ins36, NULL, NULL, cta_res);
592 if(l < 0 || !status_ok(cta_res + l))
594 rdr_log(reader, "Ins36: failed");
598 break;
601 case 0x10: // loc_43C203
603 uint8_t ins7411[5] = { 0xD3,0x74,0x11,0x00,0x00 };
604 l = read_cmd_len(reader, ins7411);
605 ins7411[4] = l + 0x10;
606 l = do_cmd(reader, ins7411, NULL, NULL, cta_res);
608 if(l < 0 || !status_ok(cta_res))
610 rdr_log(reader, "classD3 ins7411: failed");
612 break;
615 case 0x00: // normal state
617 break;
620 default:
622 rdr_log(reader, "unknown ins5C state: %02X %02X %02X %02X",
623 cta_res[0], cta_res[1], cta_res[2], cta_res[3]);
624 break;
628 reader->last_poll = now;
632 static int32_t videoguard2_card_init(struct s_reader *reader, ATR *newatr)
634 get_hist;
635 if((hist_size < 7) || (hist[1] != 0xB0) || (hist[4] != 0xFF) || (hist[5] != 0x4A) || (hist[6] != 0x50))
637 rdr_log_dbg(reader, D_READER, "failed history check");
638 return ERROR;
640 rdr_log_dbg(reader, D_READER, "passed history check");
642 get_atr;
643 def_resp;
645 if(!cs_malloc(&reader->csystem_data, sizeof(struct videoguard_data)))
647 return ERROR;
649 struct videoguard_data *csystem_data = reader->csystem_data;
651 // set information on the card stored in reader-videoguard-common.c
652 set_known_card_info(reader, atr, &atr_size);
654 if((reader->ndsversion != NDS2) && (((csystem_data->card_system_version != NDS2)
655 && (csystem_data->card_system_version != NDSUNKNOWN)) || (reader->ndsversion != NDSAUTO)))
657 /* known ATR and not NDS2
658 or known NDS2 ATR and forced to another NDS version */
659 return ERROR;
662 rdr_log_dbg(reader, D_READER, "type: %s, baseyear: %i", csystem_data->card_desc, csystem_data->card_baseyear);
663 if(reader->ndsversion == NDS2)
665 rdr_log_dbg(reader, D_READER, "forced to NDS2");
668 // a non videoguard2/NDS2 card will fail on read_cmd_len(ins7401)
669 // this way unknown videoguard2/NDS2 cards will also pass this check
671 uint8_t ins7401[5] = { 0xD0, 0x74, 0x01, 0x00, 0x00 };
672 int32_t l;
673 if((l = read_cmd_len(reader, ins7401)) < 0) // not a videoguard2/NDS card or communication error
675 return ERROR;
678 ins7401[4] = l;
679 if(!write_cmd_vg(ins7401, NULL) || !status_ok(cta_res + l))
681 rdr_log(reader, "classD0 ins7401: failed - cmd list not read");
682 return ERROR;
685 memorize_cmd_table(reader, cta_res, l);
687 uint8_t buff[256];
688 static const uint8_t ins02[5] = { 0xD0, 0x02, 0x00, 0x00, 0x08 };
690 // D0 02 command is not always present in command table but should be supported
691 // on most cards so do not use do_cmd()
692 if(!write_cmd_vg(ins02, NULL) || !status_ok(cta_res + 8))
694 rdr_log(reader, "Unable to get NDS ROM version.");
696 else
698 int i;
699 for(i = 0; i < 8; i++)
701 if(cta_res[i] <= 0x09)
703 cta_res[i] = cta_res[i] + 0x30;
705 else if(!isalnum(cta_res[i]))
707 cta_res[i] = '*';
710 memset(reader->rom, 0, sizeof(reader->rom));
711 memcpy(reader->rom, cta_res, 4);
712 reader->rom[4] = '-';
713 memcpy(reader->rom + 5, cta_res + 4, 4);
715 rdr_log(reader, "Card type: %c%c%c%c", reader->rom[0], reader->rom[1], reader->rom[2], reader->rom[3]);
716 rdr_log(reader, "Rom version: %c%c%c%c", reader->rom[5], reader->rom[6], reader->rom[7], reader->rom[8]);
719 // get Vg credit on card
720 uint8_t ins7404[5] = { 0xD0, 0x74, 0x04, 0x00, 0x00 };
721 if((l = read_cmd_len(reader, ins7404)) > 0) // get command len for ins7404
723 ins7404[4] = l;
724 if(!write_cmd_vg(ins7404, NULL) || !status_ok(cta_res + l))
726 rdr_log(reader, "classD0 ins7404: failed");
728 else
730 if(cta_res[0] == 0x15)
732 reader->VgCredit = ((cta_res[8] << 8) + cta_res[9]) / 100;
733 rdr_log(reader, "Credit available on card: %i euro", reader->VgCredit);
737 else // case V13
739 rdr_log(reader, "Unable to get smartcard credit");
742 static const uint8_t ins7416[5] = { 0xD0, 0x74, 0x16, 0x00, 0x00 };
744 if(do_cmd(reader, ins7416, NULL, NULL, cta_res) < 0)
746 rdr_log(reader, "classD0 ins7416: failed");
747 return ERROR;
749 uint8_t boxID [4];
751 if(reader->boxid > 0)
753 // the boxid is specified in the config
754 int32_t i;
755 for(i = 0; i < 4; i++)
757 boxID[i] = (reader->boxid >> (8 * (3 - i))) % 0x100;
760 else
762 uint8_t ins36[5] = { 0xD0, 0x36, 0x00, 0x00, 0x00 };
763 static const uint8_t ins5e[5] = { 0xD0, 0x5E, 0x00, 0x0C, 0x02 };
765 // we can try to get the boxid from the card
766 int32_t boxidOK = 0;
767 l = read_cmd_len(reader, ins36);
768 if(l > 0)
770 ins36[4] = l;
772 else if(cmd_exists(reader, ins5e))
774 if(!write_cmd_vg(ins5e, NULL) || !status_ok(cta_res + 2))
776 rdr_log(reader, "classD0 ins5e: failed");
778 else
780 ins36[3] = cta_res[0];
781 ins36[4] = cta_res[1];
785 l = ins36[4];
786 if(!write_cmd_vg(ins36, NULL) || !status_ok(cta_res + l))
788 rdr_log(reader, "classD0 ins36: failed");
789 return ERROR;
792 memcpy(buff, ins36, 5);
793 memcpy(buff + 5, cta_res, l);
794 memcpy(buff + 5 + l, cta_res + l, 2);
796 if(l < 13)
798 rdr_log(reader, "classD0 ins36: answer too int16");
800 else if(buff[7] > 0x0F)
802 rdr_log(reader, "classD0 ins36: encrypted - can't parse");
804 else
806 // skipping the initial fixed fields: cmdecho (4) + length (1) + encr/rev++ (4)
807 int32_t i = 9;
808 int32_t gotUA = 0;
809 while(i < l)
811 if(!gotUA && buff[i] < 0xF0) // then we guess that the next 4 bytes is the UA
813 gotUA = 1;
814 i += 4;
816 else
818 switch(buff[i]) // object length vary depending on type
820 case 0x00: // padding
821 i += 1;
822 break;
824 case 0xEF: // card status
825 i += 3;
826 break;
828 case 0xD1:
829 i += 4;
830 break;
832 case 0xDF: // next server contact
833 i += 5;
834 break;
836 case 0xF3: // boxID
837 memcpy(boxID, buff + i + 1, sizeof(boxID));
838 boxidOK = 1;
839 i += 5;
840 break;
842 case 0xF6:
843 i += 6;
844 break;
846 case 0x01: // date & time
847 i += 7;
848 break;
850 case 0xFA:
851 i += 9;
852 break;
854 case 0x5E:
855 case 0x67: // signature
856 case 0xDE:
857 case 0xE2:
858 case 0xE9: // tier dates
859 case 0xF8: // Old PPV Event Record
860 case 0xFD:
861 i += buff[i + 1] + 2; // skip length + 2 bytes (type and length)
862 break;
864 default: // default to assume a length byte
865 rdr_log(reader, "classD0 ins36: returned unknown type=0x%02X - parsing may fail", buff[i]);
866 i += buff[i + 1] + 2;
872 if(!boxidOK)
874 rdr_log(reader, "no boxID available");
875 return ERROR;
879 uint8_t ins4C[5] = { 0xD0, 0x4C, 0x00, 0x00, 0x09 };
880 uint8_t len4c = 0, mode = 0;
881 uint8_t payload4C[0xF] = { 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
883 if(cmd_table_get_info(reader, ins4C, &len4c, &mode))
885 ins4C[4] = len4c; // don't mind if payload is > of ins len, it will be cutted after write_cmd_vg()
886 if(len4c > 9)
888 rdr_log_dbg(reader, D_READER, "extended ins4C detected");
891 memcpy(payload4C, boxID, 4);
892 if(!write_cmd_vg(ins4C, payload4C))
894 rdr_log(reader, "classD0 ins4C: failed - sending boxid failed");
895 return ERROR;
898 int d37423_ok = 0;
899 static const uint8_t ins7403[5] = { 0xD0, 0x74, 0x03, 0x00, 0x00 }; // taken from v13 boot log
900 if(do_cmd(reader, ins7403, NULL, NULL, cta_res) < 0)
902 rdr_log(reader, "classD0 ins7403: failed");
904 else
906 d37423_ok = (cta_res[2] >> 5) & 1;
909 if(reader->ins7E11[0x01]) // the position of the ins7E is taken from v13 log
911 uint8_t ins742b[5] = { 0xD0, 0x74, 0x2b, 0x00, 0x00 };
912 l = read_cmd_len(reader, ins742b); // get command len for ins742b
914 if(l < 2)
916 rdr_log(reader, "No TA1 change for this card is possible by ins7E11");
918 else
920 ins742b[4] = l;
921 bool ta1ok = 0;
922 if(!write_cmd_vg(ins742b, NULL) || !status_ok(cta_res + ins742b[4])) // get supported TA1 bytes
924 rdr_log(reader, "classD0 ins742b: failed");
925 return ERROR;
927 else
929 int32_t i;
930 for(i = 2; i < l; i++)
932 if(cta_res[i] == reader->ins7E11[0x00])
934 ta1ok = 1;
935 break;
940 if(ta1ok == 0)
942 rdr_log(reader, "The value %02X of ins7E11 is not supported,try one between %02X and %02X",
943 reader->ins7E11[0x00], cta_res[2], cta_res[ins742b[4] - 1]);
945 else
947 static const uint8_t ins7E11[5] = { 0xD0, 0x7E, 0x11, 0x00, 0x01 };
948 reader->ins7e11_fast_reset = 0;
949 l = do_cmd(reader, ins7E11, reader->ins7E11, NULL, cta_res);
951 if(l < 0 || !status_ok(cta_res))
953 rdr_log(reader, "classD0 ins7E11: failed");
954 return ERROR;
956 else
958 uint8_t TA1;
959 if(ATR_GetInterfaceByte(newatr, 1, ATR_INTERFACE_BYTE_TA, &TA1) == ATR_OK)
961 if(TA1 != reader->ins7E11[0x00])
963 rdr_log(reader, "classD0 ins7E11: Scheduling card reset for TA1 change from %02X to %02X", TA1, reader->ins7E11[0x00]);
964 reader->ins7e11_fast_reset = 1;
966 #if defined(WITH_COOLAPI) || defined(WITH_COOLAPI2)
967 if(reader->typ == R_MOUSE || reader->typ == R_SC8in1 || reader->typ == R_SMART || reader->typ == R_INTERNAL)
969 #else
970 if(reader->typ == R_MOUSE || reader->typ == R_SC8in1 || reader->typ == R_SMART)
972 #endif
973 add_job(reader->client, ACTION_READER_RESET_FAST, NULL, 0);
975 else
977 add_job(reader->client, ACTION_READER_RESTART, NULL, 0);
979 return OK; // Skip the rest of the init since the card will be reset anyway
987 //int16_t int32_t SWIRDstatus = cta_res[1];
988 static const uint8_t ins58[5] = { 0xD0, 0x58, 0x00, 0x00, 0x00 };
989 l = do_cmd(reader, ins58, NULL, NULL, cta_res);
991 if(l < 0)
993 rdr_log(reader, "classD0 ins58: failed");
994 return ERROR;
997 memset(reader->hexserial, 0, 8);
998 memcpy(reader->hexserial + 2, cta_res + 3, 4);
999 memcpy(reader->sa, cta_res + 3, 3);
1000 reader->caid = cta_res[24] * 0x100 + cta_res[25];
1001 reader->VgFuse = cta_res[2];
1002 rdr_log(reader, "FuseByte: %02X", reader->VgFuse);
1003 memset(reader->VgRegionC, 0, 8);
1004 memcpy(reader->VgRegionC, cta_res + 60, 8);
1006 rdr_log(reader, "Region Code: %c%c%c%c%c%c%c%c",
1007 reader->VgRegionC[0], reader->VgRegionC[1],
1008 reader->VgRegionC[2], reader->VgRegionC[3],
1009 reader->VgRegionC[4], reader->VgRegionC[5],
1010 reader->VgRegionC[6], reader->VgRegionC[7]);
1012 memset(reader->VgCountryC, 0, 3);
1013 memcpy(reader->VgCountryC, cta_res + 55, 3);
1014 rdr_log(reader, "Country Code: %c%c%c", reader->VgCountryC[0], reader->VgCountryC[1], reader->VgCountryC[2]);
1016 // we have one provider, 0x0000
1017 reader->nprov = 1;
1018 memset(reader->prid, 0x00, sizeof(reader->prid));
1020 cCamCryptVG_SetSeed(reader);
1022 static const uint8_t insB4[5] = { 0xD0, 0xB4, 0x00, 0x00, 0x40 };
1023 uint16_t tbuff[32];
1024 cCamCryptVG_GetCamKey(reader, tbuff);
1025 l = do_cmd(reader, insB4, (uint8_t *)tbuff, NULL, cta_res);
1026 if(l < 0 || !status_ok(cta_res))
1028 rdr_log(reader, "classD0 insB4: failed");
1029 return ERROR;
1032 static const uint8_t insBC[5] = { 0xD0, 0xBC, 0x00, 0x00, 0x00 };
1033 l = do_cmd(reader, insBC, NULL, NULL, cta_res);
1034 if(l < 0)
1036 rdr_log(reader, "classD0 insBC: failed");
1037 return ERROR;
1040 // Class D1/D3 instructions only work after this point
1042 static const uint8_t insBE[5] = { 0xD3, 0xBE, 0x00, 0x00, 0x00 };
1043 l = do_cmd(reader, insBE, NULL, NULL, cta_res);
1044 if(l < 0)
1046 rdr_log(reader, "classD3 insBE: failed");
1047 return ERROR;
1050 static const uint8_t ins58a[5] = { 0xD1, 0x58, 0x00, 0x00, 0x00 };
1051 l = do_cmd(reader, ins58a, NULL, NULL, cta_res);
1052 if(l < 0)
1054 rdr_log(reader, "classD1 ins58: failed");
1055 return ERROR;
1058 // new ins74 present at boot
1059 if(d37423_ok) // from ins7403 answer
1061 static const uint8_t ins7423[5] = { 0xD3, 0x74, 0x23, 0x00, 0x00 };
1062 if(do_cmd(reader, ins7423, NULL, NULL, cta_res) < 0)
1064 rdr_log(reader, "classD1 ins7423: failed");
1068 static const uint8_t ins742A[5] = { 0xD1, 0x74, 0x2A, 0x00, 0x00 };
1069 if(do_cmd(reader, ins742A, NULL, NULL, cta_res) < 0)
1071 rdr_log(reader, "classD1 ins742A: failed");
1074 static const uint8_t ins741C[5] = { 0xD1, 0x74, 0x1C, 0x00, 0x00 };
1075 if(do_cmd(reader, ins741C, NULL, NULL, cta_res) < 0)
1077 rdr_log(reader, "classD1 ins741C: failed");
1080 static const uint8_t ins4Ca[5] = { 0xD1, 0x4C, 0x00, 0x00, 0x00 };
1082 payload4C[4] = 0x83;
1084 l = do_cmd(reader, ins4Ca, payload4C, NULL, cta_res);
1085 if(l < 0 || !status_ok(cta_res))
1087 rdr_log(reader, "classD1 ins4Ca: failed");
1088 return ERROR;
1090 memcpy(reader->payload4C, payload4C, 0xF);
1092 if(reader->ins7E[0x1A])
1094 static const uint8_t ins7E[5] = { 0xD1, 0x7E, 0x10, 0x00, 0x1A };
1095 l = do_cmd(reader, ins7E, reader->ins7E, NULL, cta_res);
1096 if(l < 0 || !status_ok(cta_res))
1098 rdr_log(reader, "classD1 ins7E: failed");
1099 return ERROR;
1103 // get PIN settings
1104 static const uint8_t ins7411[5] = { 0xD1, 0x74, 0x11, 0x00, 0x00 };
1105 uint8_t payload2e4[4];
1106 if(do_cmd(reader, ins7411, NULL, NULL, cta_res) < 0)
1108 rdr_log(reader, "classD1 ins7411: unable to get PIN");
1109 return ERROR;
1111 else
1113 memset(payload2e4, 0, 4);
1114 memcpy(payload2e4, cta_res + 2, 4);
1115 reader->VgPin = (cta_res[4] << 8) + cta_res[5];
1116 rdr_log(reader, "Pincode read: %04hu", reader->VgPin);
1119 // get PCB(content rating) settings
1120 static const uint8_t ins74e[5] = { 0xD1, 0x74, 0x0E, 0x00, 0x00 };
1121 if(do_cmd(reader, ins74e, NULL, NULL, cta_res) < 0)
1123 rdr_log(reader, "classD1 ins74e: failed to get PCB settings");
1125 else
1127 rdr_log(reader, "PCB settings: %X %X %X %X", cta_res[2], cta_res[3], cta_res[4], cta_res[5]);
1130 // send PIN
1131 static const uint8_t ins2epin[5] = { 0xD1, 0x2E, 0x04, 0x00, 0x04 };
1132 if(cfg.ulparent)
1134 l = do_cmd(reader, ins2epin, payload2e4, NULL, cta_res);
1135 if(l < 0 || !status_ok(cta_res))
1137 rdr_log(reader, "classD1 ins2E: failed");
1138 rdr_log(reader, "Cannot disable parental control");
1139 return ERROR;
1141 else
1143 rdr_log(reader, "Parental control disabled");
1147 // send check control for pin, needed on some cards
1148 // the presence and the value of payloads is provider's dependent*/
1149 if(reader->ins2e06[4])
1151 static const uint8_t ins2e06[5] = { 0xD1, 0x2E, 0x06, 0x00, 0x04 };
1152 l = do_cmd(reader, ins2e06, reader->ins2e06, NULL, cta_res);
1153 if(l < 0 || !status_ok(cta_res))
1155 rdr_log(reader, "classD1 ins2E: failed");
1156 return ERROR;
1160 // fix for 09ac cards
1161 uint8_t dimeno_magic[0x10] = { 0xF9, 0xFB, 0xCD, 0x5A, 0x76, 0xB5, 0xC4, 0x5C,
1162 0xC8, 0x2E, 0x1D, 0xE1, 0xCC, 0x5B, 0x6B, 0x02 };
1164 int32_t a;
1165 for(a = 0; a < 4; a++)
1167 dimeno_magic[a] = dimeno_magic[a] ^ boxID[a];
1170 AES_set_decrypt_key(dimeno_magic, 128, &(csystem_data->astrokey));
1172 rdr_log(reader, "type: %s, caid: %04X", csystem_data->card_desc, reader->caid);
1173 rdr_log_sensitive(reader, "serial: {%02X%02X%02X%02X}, BoxID: {%02X%02X%02X%02X}, baseyear: %i",
1174 reader->hexserial[2],
1175 reader->hexserial[3],
1176 reader->hexserial[4],
1177 reader->hexserial[5],
1178 boxID[0],
1179 boxID[1],
1180 boxID[2],
1181 boxID[3],
1182 csystem_data->card_baseyear);
1184 rdr_log(reader, "ready for requests");
1186 return OK;
1189 static int32_t videoguard2_do_ecm(struct s_reader *reader, const ECM_REQUEST *er, struct s_ecm_answer *ea)
1191 uint8_t cta_res[CTA_RES_LEN];
1192 static const char valid_ecm[] = { 0x00, 0x00, 0x01 };
1193 uint8_t ins40[5] = { 0xD1, 0x40, 0x00, 0x80, 0xFF };
1194 static const uint8_t ins54[5] = { 0xD3, 0x54, 0x00, 0x00, 0x00};
1195 int32_t posECMpart2 = er->ecm[6] + 7;
1196 int32_t lenECMpart2 = er->ecm[posECMpart2] + 1;
1197 uint8_t tbuff[264], rbuff[264];
1198 const uint8_t *EcmIrdHeader = er->ecm + 5;
1199 tbuff[0] = 0;
1201 memset(ea->cw + 0, 0, 16); // set cw to 0 so client will know it is invalid unless it is overwritten with a valid cw
1202 int32_t chk;
1203 chk = checksum_ok(EcmIrdHeader);
1205 if((memcmp(&(er->ecm[3]), valid_ecm, sizeof(valid_ecm)) != 0) || (chk == 0))
1207 rdr_log(reader, "Not a valid ecm");
1208 return E_CORRUPT;
1210 memcpy(tbuff + 1, er->ecm + posECMpart2 + 1, lenECMpart2 - 1);
1212 int32_t new_len = lenECMpart2;
1213 if(reader->fix_9993 && reader->caid == 0x919 && tbuff[1] == 0x7F)
1215 tbuff[1] = 0x47;
1216 tbuff[2] = 0x08;
1217 memmove(tbuff + 11, tbuff + 13, new_len - 11);
1218 new_len -= 2;
1221 ins40[4] = new_len;
1222 int32_t l;
1223 l = do_cmd(reader, ins40, tbuff, NULL, cta_res);
1225 if(l < 0 || !status_ok(cta_res))
1227 rdr_log(reader, "classD1 ins40: (%d) status not ok %02x %02x", l, cta_res[0], cta_res[1]);
1228 rdr_log(reader, "The card is not answering correctly! Restarting reader for safety");
1229 add_job(reader->client, ACTION_READER_RESTART, NULL, 0);
1230 return ERROR;
1232 else
1234 l = do_cmd(reader, ins54, NULL, rbuff, cta_res);
1235 if(l < 0 || !status_ok(cta_res + l))
1237 rdr_log(reader, "classD3 ins54: (%d) status not ok %02x %02x", l, cta_res[0], cta_res[1]);
1238 rdr_log(reader, "The card is not answering correctly! Restarting reader for safety");
1239 add_job(reader->client, ACTION_READER_RESTART, NULL, 0);
1240 return ERROR;
1242 else
1244 struct videoguard_data *csystem_data = reader->csystem_data;
1245 uint8_t *payload = rbuff + 5;
1246 uint8_t buff_0F[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1247 uint8_t buff_56[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1248 uint8_t buff_55[1] = { 0x00 };
1249 uint8_t tag, t_len;
1250 uint8_t *t_body;
1251 int32_t payloadLen = rbuff[4];
1252 int32_t ind = 8 + 6; // +8 (CW1), +2 (cw checksum) + 2 (tier used) +2 (result byte)
1254 while(ind < payloadLen)
1256 tag = payload[ind];
1257 t_len = payload[ind + 1]; // len of the tag
1258 t_body = payload + ind + 2; // body of the tag
1260 switch(tag)
1262 case 0x0F: // Debug ecm info
1263 if(t_len > 6)
1265 t_len = 6;
1267 memcpy(buff_0F, t_body, t_len);
1268 break;
1270 case 0x25: // CW2 tag
1271 memcpy(ea->cw + 8, t_body +1, 8);
1272 break;
1274 case 0x55: // cw crypt info tag
1275 memcpy(buff_55, t_body, 1 );
1276 break;
1278 case 0x56: // tag data for astro
1279 memcpy(buff_56, t_body, 8);
1280 break;
1282 default:
1283 break;
1285 ind += t_len + 2;
1288 if(12 < payloadLen)
1290 ea->tier = b2i(2, &payload[10]);
1293 memcpy(reader->VgLastPayload, buff_0F, 6);
1295 int32_t test_0F = 1;
1296 if(!cw_is_valid(rbuff + 5)) // sky cards report 90 00 = ok but send cw = 00 when something goes wrong :(
1298 if(buff_0F[0] & 1) // case 0f_0x 01 xx xx xx xx xx
1300 rdr_log(reader, "classD3 ins54: no cw --> Bad/wrong ECM");
1301 test_0F = 0;
1304 if(buff_0F[1] & 1) // case 0f_0x xx 01 xx xx xx xx
1306 rdr_log(reader, "classD3 ins54: no cw --> Card appears in error");
1307 test_0F = 0;
1310 if((buff_0F[0] >> 1) & 1) // case 0f_0x 02 xx xx xx xx xx
1312 rdr_log(reader, "classD3 ins54: no cw --> Card isn't active");
1313 test_0F = 0;
1315 else // These Messages are only nessensary if the Card is active
1317 if((buff_0F[1] >> 4) & 1) // case 0f_0x xx 10 xx xx xx xx
1319 rdr_log(reader, "classD3 ins54: no cw --> Card needs pairing/extra data");
1320 if((reader->caid == 0x98C || reader->caid == 0x98D) && (buff_0F[5] == 0)){ //case 0f_0x xx 10 xx xx xx 00
1321 rdr_log(reader, "classD3 ins54: no cw --> unassigned Boxid");
1323 test_0F = 0;
1326 if((buff_0F[1] >> 5) & 1) // case 0f_0x xx 20 xx xx xx xx
1328 rdr_log(reader, "classD3 ins54: no cw --> No tier found"); //check this
1329 test_0F = 0;
1332 if((buff_0F[2] >> 5) & 1) // case 0f_0x xx xx 20 xx xx xx
1334 rdr_log(reader, "classD3 ins54: no cw --> Tier expired");
1335 test_0F = 0;
1338 if((buff_0F[1] >> 6) & 1) // case 0f_0x xx 40 xx xx xx xx
1340 rdr_log(reader, "classD3 ins54: no cw --> Card needs pin");
1341 test_0F = 0;
1344 if((reader->caid == 0x98C || reader->caid == 0x98D) && ((buff_0F[5] >> 3) & 1)) //case 0f_0x xx xx xx xx xx XX = binary xxxx1xxx
1346 rdr_log(reader, "classD3 ins54: no cw --> CW-overcrypt%s is required! (Debug-ECM-Info: 0F_06 %02X %02X %02X %02X %02X %02X)",
1347 (((buff_0F[5] >> 1) & 1) ? " (and assignment)" : ""), buff_0F[0], buff_0F[1], buff_0F[2], buff_0F[3], buff_0F[4], buff_0F[5]); //case 0f_0x xx xx xx xx xx XX = binary xxxx1x?x
1351 if(test_0F) // case unknown error
1353 rdr_log(reader, "classD3 ins54: status 90 00 = ok but cw=00 tag 0F: %02X %02X %02X %02X %02X %02X, please report to the developers with decrypted ins54",
1354 buff_0F[0], buff_0F[1], buff_0F[2], buff_0F[3], buff_0F[4], buff_0F[5]);
1356 return ERROR;
1359 // copy cw1 in place
1360 memcpy(ea->cw + 0, rbuff + 5, 8);
1362 // case 55_01 xx where bit0==1, CW is crypted
1363 if(buff_55[0] & 1)
1365 if((buff_55[0] >> 3) & 1) //case 55_01 xx where bit3==1, CW-Overcrypt may not required
1367 rdr_log_dbg(reader, D_READER, "classD3 ins54: Tag55_01 = %02X, CW-overcrypt may not required", buff_55[0]);
1369 if(~((buff_55[0] >> 2) & 1)) //case 55_01 xx where bit2==0, no AES overcrypt
1371 if((buff_55[0] >> 1) & 1) //case 55_01 xx where bit1==1, unique Pairing
1373 rdr_log_dbg(reader, D_READER, "classD3 ins54: CW is crypted, trying to decrypt unique pairing mode 0x%02X", buff_55[0]);
1374 if(er->ecm[0] & 1){ //log crypted CW
1375 rdr_log_dbg(reader, D_READER, "crypted CW is: 0000000000000000%02X%02X%02X%02X%02X%02X%02X%02X", ea->cw[0], ea->cw[1], ea->cw[2], ea->cw[3], ea->cw[4], ea->cw[5], ea->cw[6], ea->cw[7]);
1376 } else {
1377 rdr_log_dbg(reader, D_READER, "crypted CW is: %02X%02X%02X%02X%02X%02X%02X%02X0000000000000000", ea->cw[0], ea->cw[1], ea->cw[2], ea->cw[3], ea->cw[4], ea->cw[5], ea->cw[6], ea->cw[7]);
1379 if((reader->k1_unique[16] == 0x08) || (reader->k1_unique[16] == 0x10)) //check k1 for unique pairing mode is DES(8 bytes) or 3DES(16 bytes) long
1381 if(reader->k1_unique[16] == 0x08){
1382 rdr_log_dbg(reader, D_READER, "use k1(DES) for CW decryption in unique pairing mode");
1383 des_ecb_decrypt(ea->cw, reader->k1_unique, 0x08);
1385 else
1387 rdr_log_dbg(reader, D_READER, "use k1(3DES) for CW decryption in unique pairing mode");
1388 des_ecb3_decrypt(ea->cw, reader->k1_unique);
1390 if(er->ecm[0] & 1){ //log decrypted CW
1391 rdr_log_dbg(reader, D_READER, "decrypted CW is: 0000000000000000%02X%02X%02X%02X%02X%02X%02X%02X", ea->cw[0], ea->cw[1], ea->cw[2], ea->cw[3], ea->cw[4], ea->cw[5], ea->cw[6], ea->cw[7]);
1392 } else {
1393 rdr_log_dbg(reader, D_READER, "decrypted CW is: %02X%02X%02X%02X%02X%02X%02X%02X0000000000000000", ea->cw[0], ea->cw[1], ea->cw[2], ea->cw[3], ea->cw[4], ea->cw[5], ea->cw[6], ea->cw[7]);
1396 else
1398 rdr_log_dbg(reader, D_READER, "k1 for unique pairing mode is not set");
1399 return ERROR;
1402 else //case 55_01 xx where bit1==0, generic Pairing
1404 rdr_log_dbg(reader, D_READER, "classD3 ins54: CW is crypted, trying to decrypt generic pairing mode 0x%02X", buff_55[0]);
1405 if(er->ecm[0] & 1){ //log crypted CW
1406 rdr_log_dbg(reader, D_READER, "crypted CW is: 0000000000000000%02X%02X%02X%02X%02X%02X%02X%02X", ea->cw[0], ea->cw[1], ea->cw[2], ea->cw[3], ea->cw[4], ea->cw[5], ea->cw[6], ea->cw[7]);
1407 } else {
1408 rdr_log_dbg(reader, D_READER, "crypted CW is: %02X%02X%02X%02X%02X%02X%02X%02X0000000000000000", ea->cw[0], ea->cw[1], ea->cw[2], ea->cw[3], ea->cw[4], ea->cw[5], ea->cw[6], ea->cw[7]);
1410 if((reader->k1_generic[16] == 0x08) || (reader->k1_generic[16] == 0x10)) //check k1 for generic pairing mode is DES(8 bytes) or 3DES(16 bytes) long
1412 if(reader->k1_generic[16] == 0x08){
1413 rdr_log_dbg(reader, D_READER, "use k1(DES) for CW decryption in generic pairing mode");
1414 des_ecb_decrypt(ea->cw, reader->k1_generic, 0x08);
1416 else
1418 rdr_log_dbg(reader, D_READER, "use k1(3DES) for CW decryption in generic pairing mode");
1419 des_ecb3_decrypt(ea->cw, reader->k1_generic);
1421 if(er->ecm[0] & 1){ //log decrypted CW
1422 rdr_log_dbg(reader, D_READER, "decrypted CW is: 0000000000000000%02X%02X%02X%02X%02X%02X%02X%02X", ea->cw[0], ea->cw[1], ea->cw[2], ea->cw[3], ea->cw[4], ea->cw[5], ea->cw[6], ea->cw[7]);
1423 } else {
1424 rdr_log_dbg(reader, D_READER, "decrypted CW is: %02X%02X%02X%02X%02X%02X%02X%02X0000000000000000", ea->cw[0], ea->cw[1], ea->cw[2], ea->cw[3], ea->cw[4], ea->cw[5], ea->cw[6], ea->cw[7]);
1427 else
1429 rdr_log_dbg(reader, D_READER, "k1 for generic pairing mode is not set");
1430 return ERROR;
1434 else //unkown pairing mode or AES overcrypt
1436 rdr_log_dbg(reader, D_READER, "classD3 ins54: CW is crypted, unknown pairing mode 0x%02X, AES overcrypt?", buff_55[0]);
1437 if(er->ecm[0] & 1){ //log crypted CW
1438 rdr_log_dbg(reader, D_READER, "crypted CW is: 0000000000000000%02X%02X%02X%02X%02X%02X%02X%02X", ea->cw[0], ea->cw[1], ea->cw[2], ea->cw[3], ea->cw[4], ea->cw[5], ea->cw[6], ea->cw[7]);
1439 } else {
1440 rdr_log_dbg(reader, D_READER, "crypted CW is: %02X%02X%02X%02X%02X%02X%02X%02X0000000000000000", ea->cw[0], ea->cw[1], ea->cw[2], ea->cw[3], ea->cw[4], ea->cw[5], ea->cw[6], ea->cw[7]);
1442 return ERROR;
1446 // case 55_01 xx where bit2==1, old dimeno_PostProcess_Decrypt(reader, rbuff, ea->cw);
1447 if((buff_55[0] >> 2) & 1)
1449 uint8_t buffer[0x10];
1450 memcpy(buffer, rbuff + 5, 8);
1451 memcpy(buffer + 8, buff_56, 8);
1452 AES_decrypt(buffer, buffer, &(csystem_data->astrokey));
1453 memcpy(ea->cw + 0, buffer, 8); // copy calculated CW in right place
1456 if(new_len != lenECMpart2)
1458 memcpy(ea->cw, ea->cw + 8, 8);
1459 memset(ea->cw + 8, 0, 8);
1462 // test for postprocessing marker
1463 int32_t posB0 = -1;
1464 int32_t i;
1465 for(i = 6; i < posECMpart2; i++)
1467 if(er->ecm[i - 3] == 0x80 && er->ecm[i] == 0xB0 && ((er->ecm[i + 1] == 0x01) || (er->ecm[i + 1] == 0x02) || (er->ecm[i + 1] == 0x03)))
1469 posB0 = i;
1470 break;
1474 if(posB0 != -1 && (reader->caid == 0x919 || reader->caid == 0x93B || reader->caid == 0x9CD || reader->caid == 0x9C1))
1476 do_post_dw_hash(reader, ea->cw + 0, &er->ecm[posB0 - 2]);
1477 do_post_dw_hash(reader, ea->cw + 8, &er->ecm[posB0 - 2]);
1480 if(reader->caid == 0x0907) // quickfix: cw2 is not a valid cw, something went wrong before
1482 memset(ea->cw + 8, 0, 8);
1483 if(er->ecm[0] & 1)
1485 memcpy(ea->cw + 8, ea->cw, 8);
1486 memset(ea->cw, 0, 8);
1489 else
1491 if(er->ecm[0] & 1)
1493 uint8_t tmpcw[8];
1494 memcpy(tmpcw, ea->cw + 8, 8);
1495 memcpy(ea->cw + 8, ea->cw + 0, 8);
1496 memcpy(ea->cw + 0, tmpcw, 8);
1500 return OK;
1505 static int32_t videoguard2_do_emm(struct s_reader *reader, EMM_PACKET *ep)
1507 return videoguard_do_emm(reader, ep, 0xD1, vg2_read_tiers, do_cmd);
1510 static int32_t videoguard2_card_info(struct s_reader *reader)
1512 // info is displayed in init, or when processing info
1513 struct videoguard_data *csystem_data = reader->csystem_data;
1514 rdr_log(reader, "card detected");
1515 rdr_log(reader, "type: %s", csystem_data->card_desc);
1517 if(reader->ins7e11_fast_reset != 1)
1519 vg2_read_tiers(reader);
1521 return OK;
1524 static void videoguard2_card_done(struct s_reader *reader)
1526 struct videoguard_data *csystem_data = reader->csystem_data;
1527 if(csystem_data)
1529 NULLFREE(csystem_data->cmd_table);
1533 const struct s_cardsystem reader_videoguard2 =
1535 .desc = "videoguard2",
1536 .caids = (uint16_t[]){ 0x09, 0 },
1537 .do_emm = videoguard2_do_emm,
1538 .do_ecm = videoguard2_do_ecm,
1539 .card_info = videoguard2_card_info,
1540 .card_init = videoguard2_card_init,
1541 .poll_status = videoguard2_poll_status,
1542 .card_done = videoguard2_card_done,
1543 .get_emm_type = videoguard_get_emm_type,
1544 .get_emm_filter = videoguard_get_emm_filter,
1547 #endif