- fix Building without Nagra not possible at Nagra_Merlin https://trac.streamboard...
[oscam.git] / reader-videoguard2.c
blobc8bb8bcc36b086e98a8a653ea8461e888245c845
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 too 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 = ((TierClass << 8) + (word << 3) + bitnum);
309 cs_add_entitlement(reader, reader->caid, b2ll(4, reader->prid[0]), tier_id, TierClass, start_t, end_t, 4, 1);
310 rdr_log(reader, "|-- %02x ---|-- %04x --| %04d/%02d/%02d-%02d:%02d:%02d | %s",
311 TierClass,
312 tier_id,
313 timeinfo.tm_year + 1900,
314 timeinfo.tm_mon + 1,
315 timeinfo.tm_mday,
316 timeinfo.tm_hour,
317 timeinfo.tm_min,
318 timeinfo.tm_sec,
319 get_tiername(tier_id, reader->caid, tiername));
322 if((cta_res[word + 1 + 2] >> bitnum) & 1)
324 tier_id = ((TierClass << 8) + (word << 3) + bitnum + 8);
325 cs_add_entitlement(reader, reader->caid, b2ll(4, reader->prid[0]), tier_id, TierClass, start_t, end_t, 4, 1);
326 rdr_log(reader, "|-- %02x ---|-- %04x --| %04d/%02d/%02d-%02d:%02d:%02d | %s",
327 TierClass,
328 tier_id,
329 timeinfo.tm_year + 1900,
330 timeinfo.tm_mon + 1,
331 timeinfo.tm_mday,
332 timeinfo.tm_hour,
333 timeinfo.tm_min,
334 timeinfo.tm_sec,
335 get_tiername(tier_id, reader->caid, tiername));
342 rdr_log(reader, "------------------------------------------------------from-ins70--");
344 else if(reader->readtiers == 2)
346 int32_t l;
347 // ins2a is not needed and causes an error on some cards eg Sky Italy 09CD
348 // check if ins2a is in command table before running it
350 static const uint8_t ins2a[5] = { 0xD1, 0x2a, 0x00, 0x00, 0x00 };
351 if(cmd_exists(reader, ins2a))
353 l = do_cmd(reader, ins2a, NULL, NULL, cta_res);
354 if(l < 0 || !status_ok(cta_res + l))
356 rdr_log(reader, "classD1 ins2a: failed");
357 return;
361 static const uint8_t ins76007f[5] = { 0xD1, 0x76, 0x00, 0x7f, 0x02 };
362 l = do_cmd(reader, ins76007f, NULL, NULL, cta_res);
363 if(l < 0 || !status_ok(cta_res + 2))
365 rdr_log(reader, "classD1 ins76007f: failed");
366 return;
368 int32_t num = cta_res[1];
370 int32_t i;
371 uint8_t ins76[5] = { 0xD1, 0x76, 0x00, 0x00, 0x00 };
373 // some cards start real tiers info in middle of tier info
374 // and have blank tiers between old tiers and real tiers eg 09AC
375 int32_t starttier = csystem_data->card_tierstart;
376 bool stopemptytier = 1;
377 if(!starttier)
379 stopemptytier = 0;
382 // check to see if specified start tier is blank and if blank, start at 0 and ignore blank tiers
383 ins76[2] = starttier;
384 l = do_cmd(reader, ins76, NULL, NULL, cta_res);
385 if(l < 0 || !status_ok(cta_res + l))
387 return;
390 if(cta_res[2] == 0 && cta_res[3] == 0)
392 stopemptytier = 0;
393 starttier = 0;
396 cs_clear_entitlement(reader); // reset the entitlements
397 rdr_log(reader, "------------------------------------------------------------------");
398 rdr_log(reader, "|- class -|-- tier --|----- valid to ------|--- package name ----|");
399 rdr_log(reader, "+---------+----------+---------------------+---------------------+");
400 if((reader->VgFuse&5) == 0)
402 rdr_log(reader, "|------- This card is not active, so no package available! ------|");
405 for(i = starttier; i < num; i++)
407 ins76[2] = i;
408 l = do_cmd(reader, ins76, NULL, NULL, cta_res);
410 if(l < 0 || !status_ok(cta_res + l))
412 return;
415 if(cta_res[2] == 0 && cta_res[3] == 0 && stopemptytier)
417 return;
420 if(cta_res[2] != 0 || cta_res[3] != 0)
422 char tiername[83];
423 uint16_t tier_id = (cta_res[2] << 8) | cta_res[3];
424 // add entitlements to list
425 struct tm timeinfo;
426 memset(&timeinfo, 0, sizeof(struct tm));
427 rev_date_calc_tm(&cta_res[4], &timeinfo, csystem_data->card_baseyear);
428 cs_add_entitlement(reader, reader->caid, b2ll(4, reader->prid[0]), tier_id, 0, 0, mktime(&timeinfo), 4, 1);
430 if(!stopemptytier)
432 rdr_log_dbg(reader, D_READER, "tier: %04x, tier-number: 0x%02x", tier_id, i);
434 rdr_log(reader, "|-- %02x ---|-- %04x --| %04d/%02d/%02d-%02d:%02d:%02d | %s",
435 cta_res[2],
436 tier_id,
437 timeinfo.tm_year + 1900,
438 timeinfo.tm_mon + 1,
439 timeinfo.tm_mday,
440 timeinfo.tm_hour,
441 timeinfo.tm_min,
442 timeinfo.tm_sec,
443 get_tiername(tier_id, reader->caid, tiername));
446 rdr_log(reader, "------------------------------------------------------from-ins76--");
448 else if(reader->readtiers == 0)
450 rdr_log(reader, "------------------------------------------------------------------");
451 rdr_log(reader, "|--- The reading of the tiers is disabled by the configuration --|");
452 rdr_log(reader, "------------------------------------------------------------------");
456 void videoguard2_poll_status(struct s_reader *reader)
458 const time_t poll_interval = 12; // less is better
459 time_t now = time(0);
460 int32_t i;
462 if(now >= reader->last_poll + poll_interval)
464 static const uint8_t ins5C[5] = { 0xD1, 0x5C, 0x00, 0x00, 0x04 };
465 uint8_t cta_res[CTA_RES_LEN];
466 int32_t l;
467 l = do_cmd(reader, ins5C, NULL, NULL, cta_res);
469 if(l < 0 || !status_ok(cta_res + l))
471 rdr_log(reader, "classD1 ins5C: failed");
473 else
475 switch (cta_res[1])
477 case 0x14: // loc_43C250
479 static const uint8_t ins4Ca[5] = { 0xD1, 0x4C, 0x00, 0x00, 0x00 };
480 l = do_cmd(reader, ins4Ca, reader->payload4C, NULL, cta_res);
482 if(l < 0 || !status_ok(cta_res))
484 rdr_log(reader, "classD1 ins4Ca: failed");
487 if(reader->ins7E[0x1A])
489 static const uint8_t ins7E[5] = { 0xD1, 0x7E, 0x10, 0x00, 0x1A };
490 l = do_cmd(reader, ins7E, reader->ins7E, NULL, cta_res);
492 if(l < 0 || !status_ok(cta_res))
494 rdr_log(reader, "classD1 ins7E: failed");
498 if(reader->ins2e06[4])
500 static const uint8_t ins2e06[5] = { 0xD1, 0x2E, 0x06, 0x00, 0x04 };
501 l = do_cmd(reader, ins2e06, reader->ins2e06, NULL, cta_res);
502 if(l < 0 || !status_ok(cta_res))
504 rdr_log(reader, "classD1 ins2E: failed");
508 static const uint8_t ins58a[5] = { 0xD1, 0x58, 0x00, 0x00, 0x00 };
509 if((do_cmd(reader, ins58a, NULL, NULL, cta_res) < 0))
511 rdr_log(reader, "classD1 ins58: failed");
514 reader->VgFuse = cta_res[2];
515 static const uint8_t ins7403a[5] = { 0xD1, 0x74, 0x03, 0x00, 0x00 };
517 if((do_cmd(reader, ins7403a, NULL, NULL, cta_res) < 0))
519 rdr_log(reader, "classD1 ins7403a: failed");
521 else
523 if(((cta_res[2] >> 5) & 1))
525 static const uint8_t ins7423[5] = { 0xD3, 0x74, 0x23, 0x00, 0x00 };
526 if(do_cmd(reader, ins7423, NULL, NULL, cta_res) < 0)
528 rdr_log(reader, "classD1 ins7423: failed");
532 break;
535 case 0xB: // .text:000000000043C050
537 uint8_t ins5E[5] = { 0xD1,0x5E,0x00,0x00,0x00 };
538 ins5E[2] = cta_res[2];
539 ins5E[3] = cta_res[1];
540 ins5E[4] = cta_res[3];
541 l = do_cmd(reader, ins5E, NULL, NULL, cta_res);
543 if(l < 0 || !status_ok(cta_res + l))
545 rdr_log(reader, "Ins5E: failed");
548 uint8_t ins78[5] = { 0xD1, 0x78, 0x00, 0x00, 0x18 };
549 ins78[2] = cta_res[0];
550 l = do_cmd(reader, ins78, NULL, NULL, cta_res);
552 if(l < 0 || !status_ok(cta_res + l))
554 rdr_log(reader, "classD1 ins78: failed");
557 uint8_t ins32[5] = { 0xD1, 0x32, 0x00, 0x00, 0x01 };
558 const uint8_t payload32[1] = { 0x25 };
559 l = do_cmd(reader, ins32, payload32, NULL, cta_res);
561 if(l < 0 || !status_ok(cta_res + l))
563 rdr_log(reader, "classD1 ins32: failed");
565 break;
568 case 0x0C: // loc_43C13F
570 uint8_t ins5E[5] = { 0xD1,0x5E,0x00,0x00,0x00 };
571 ins5E[2] = cta_res[2];
572 ins5E[3] = cta_res[1];
573 ins5E[4] = cta_res[3];
574 l = do_cmd(reader, ins5E, NULL, NULL, cta_res);
576 if(l < 0 || !status_ok(cta_res + l))
578 rdr_log(reader, "Ins5E: failed");
580 else
582 uint8_t ins36[5] = { 0xD1, 0x36, 0x00, 0x00, 0x00 };
583 ins36[4] = cta_res[1];
585 for (i = 0; i <= cta_res[0]; i++)
587 ins36[3] = i;
588 l = do_cmd(reader, ins36, NULL, NULL, cta_res);
590 if(l < 0 || !status_ok(cta_res + l))
592 rdr_log(reader, "Ins36: failed");
596 break;
599 case 0x10: // loc_43C203
601 uint8_t ins7411[5] = { 0xD3,0x74,0x11,0x00,0x00 };
602 l = read_cmd_len(reader, ins7411);
603 ins7411[4] = l + 0x10;
604 l = do_cmd(reader, ins7411, NULL, NULL, cta_res);
606 if(l < 0 || !status_ok(cta_res))
608 rdr_log(reader, "classD3 ins7411: failed");
610 break;
613 case 0x00: // normal state
615 break;
618 default:
620 rdr_log(reader, "unknown ins5C state: %02X %02X %02X %02X",
621 cta_res[0], cta_res[1], cta_res[2], cta_res[3]);
622 break;
626 reader->last_poll = now;
630 static int32_t videoguard2_card_init(struct s_reader *reader, ATR *newatr)
632 get_hist;
633 if((hist_size < 7) || (hist[1] != 0xB0) || (hist[4] != 0xFF) || (hist[5] != 0x4A) || (hist[6] != 0x50))
635 rdr_log_dbg(reader, D_READER, "failed history check");
636 return ERROR;
638 rdr_log_dbg(reader, D_READER, "passed history check");
640 get_atr;
641 def_resp;
643 if(!cs_malloc(&reader->csystem_data, sizeof(struct videoguard_data)))
645 return ERROR;
647 struct videoguard_data *csystem_data = reader->csystem_data;
649 // set information on the card stored in reader-videoguard-common.c
650 set_known_card_info(reader, atr, &atr_size);
652 if((reader->ndsversion != NDS2) && (((csystem_data->card_system_version != NDS2)
653 && (csystem_data->card_system_version != NDSUNKNOWN)) || (reader->ndsversion != NDSAUTO)))
655 /* known ATR and not NDS2
656 or known NDS2 ATR and forced to another NDS version */
657 return ERROR;
660 rdr_log_dbg(reader, D_READER, "type: %s, baseyear: %i", csystem_data->card_desc, csystem_data->card_baseyear);
661 if(reader->ndsversion == NDS2)
663 rdr_log_dbg(reader, D_READER, "forced to NDS2");
666 // a non videoguard2/NDS2 card will fail on read_cmd_len(ins7401)
667 // this way unknown videoguard2/NDS2 cards will also pass this check
669 uint8_t ins7401[5] = { 0xD0, 0x74, 0x01, 0x00, 0x00 };
670 int32_t l;
671 if((l = read_cmd_len(reader, ins7401)) < 0) // not a videoguard2/NDS card or communication error
673 return ERROR;
676 ins7401[4] = l;
677 if(!write_cmd_vg(ins7401, NULL) || !status_ok(cta_res + l))
679 rdr_log(reader, "classD0 ins7401: failed - cmd list not read");
680 return ERROR;
683 memorize_cmd_table(reader, cta_res, l);
685 uint8_t buff[256];
686 static const uint8_t ins02[5] = { 0xD0, 0x02, 0x00, 0x00, 0x08 };
688 // D0 02 command is not always present in command table but should be supported
689 // on most cards so do not use do_cmd()
690 if(!write_cmd_vg(ins02, NULL) || !status_ok(cta_res + 8))
692 rdr_log(reader, "Unable to get NDS ROM version.");
694 else
696 int i;
697 for(i = 0; i < 8; i++)
699 if(cta_res[i] <= 0x09)
701 cta_res[i] = cta_res[i] + 0x30;
703 else if(!isalnum(cta_res[i]))
705 cta_res[i] = '*';
708 memset(reader->rom, 0, sizeof(reader->rom));
709 memcpy(reader->rom, cta_res, 4);
710 reader->rom[4] = '-';
711 memcpy(reader->rom + 5, cta_res + 4, 4);
713 rdr_log(reader, "Card type: %c%c%c%c", reader->rom[0], reader->rom[1], reader->rom[2], reader->rom[3]);
714 rdr_log(reader, "Rom version: %c%c%c%c", reader->rom[5], reader->rom[6], reader->rom[7], reader->rom[8]);
717 // get Vg credit on card
718 uint8_t ins7404[5] = { 0xD0, 0x74, 0x04, 0x00, 0x00 };
719 if((l = read_cmd_len(reader, ins7404)) > 0) // get command len for ins7404
721 ins7404[4] = l;
722 if(!write_cmd_vg(ins7404, NULL) || !status_ok(cta_res + l))
724 rdr_log(reader, "classD0 ins7404: failed");
726 else
728 if(cta_res[0] == 0x15)
730 reader->VgCredit = ((cta_res[8] << 8) + cta_res[9]) / 100;
731 rdr_log(reader, "Credit available on card: %i euro", reader->VgCredit);
735 else // case V13
737 rdr_log(reader, "Unable to get smartcard credit");
740 static const uint8_t ins7416[5] = { 0xD0, 0x74, 0x16, 0x00, 0x00 };
742 if(do_cmd(reader, ins7416, NULL, NULL, cta_res) < 0)
744 rdr_log(reader, "classD0 ins7416: failed");
745 return ERROR;
747 uint8_t boxID [4];
749 if(reader->boxid > 0)
751 // the boxid is specified in the config
752 int32_t i;
753 for(i = 0; i < 4; i++)
755 boxID[i] = (reader->boxid >> (8 * (3 - i))) % 0x100;
758 else
760 uint8_t ins36[5] = { 0xD0, 0x36, 0x00, 0x00, 0x00 };
761 static const uint8_t ins5e[5] = { 0xD0, 0x5E, 0x00, 0x0C, 0x02 };
763 // we can try to get the boxid from the card
764 int32_t boxidOK = 0;
765 l = read_cmd_len(reader, ins36);
766 if(l > 0)
768 ins36[4] = l;
770 else if(cmd_exists(reader, ins5e))
772 if(!write_cmd_vg(ins5e, NULL) || !status_ok(cta_res + 2))
774 rdr_log(reader, "classD0 ins5e: failed");
776 else
778 ins36[3] = cta_res[0];
779 ins36[4] = cta_res[1];
783 l = ins36[4];
784 if(!write_cmd_vg(ins36, NULL) || !status_ok(cta_res + l))
786 rdr_log(reader, "classD0 ins36: failed");
787 return ERROR;
790 memcpy(buff, ins36, 5);
791 memcpy(buff + 5, cta_res, l);
792 memcpy(buff + 5 + l, cta_res + l, 2);
794 if(l < 13)
796 rdr_log(reader, "classD0 ins36: answer too int16");
798 else if(buff[7] > 0x0F)
800 rdr_log(reader, "classD0 ins36: encrypted - can't parse");
802 else
804 // skipping the initial fixed fields: cmdecho (4) + length (1) + encr/rev++ (4)
805 int32_t i = 9;
806 int32_t gotUA = 0;
807 while(i < l)
809 if(!gotUA && buff[i] < 0xF0) // then we guess that the next 4 bytes is the UA
811 gotUA = 1;
812 i += 4;
814 else
816 switch(buff[i]) // object length vary depending on type
818 case 0x00: // padding
819 i += 1;
820 break;
822 case 0xEF: // card status
823 i += 3;
824 break;
826 case 0xD1:
827 i += 4;
828 break;
830 case 0xDF: // next server contact
831 i += 5;
832 break;
834 case 0xF3: // boxID
835 memcpy(boxID, buff + i + 1, sizeof(boxID));
836 boxidOK = 1;
837 i += 5;
838 break;
840 case 0xF6:
841 i += 6;
842 break;
844 case 0x01: // date & time
845 i += 7;
846 break;
848 case 0xFA:
849 i += 9;
850 break;
852 case 0x5E:
853 case 0x67: // signature
854 case 0xDE:
855 case 0xE2:
856 case 0xE9: // tier dates
857 case 0xF8: // Old PPV Event Record
858 case 0xFD:
859 i += buff[i + 1] + 2; // skip length + 2 bytes (type and length)
860 break;
862 default: // default to assume a length byte
863 rdr_log(reader, "classD0 ins36: returned unknown type=0x%02X - parsing may fail", buff[i]);
864 i += buff[i + 1] + 2;
870 if(!boxidOK)
872 rdr_log(reader, "no boxID available");
873 return ERROR;
877 uint8_t ins4C[5] = { 0xD0, 0x4C, 0x00, 0x00, 0x09 };
878 uint8_t len4c = 0, mode = 0;
879 uint8_t payload4C[0xF] = { 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
881 if(cmd_table_get_info(reader, ins4C, &len4c, &mode))
883 ins4C[4] = len4c; // don't mind if payload is > of ins len, it will be cutted after write_cmd_vg()
884 if(len4c > 9)
886 rdr_log_dbg(reader, D_READER, "extended ins4C detected");
889 memcpy(payload4C, boxID, 4);
890 if(!write_cmd_vg(ins4C, payload4C))
892 rdr_log(reader, "classD0 ins4C: failed - sending boxid failed");
893 return ERROR;
896 if(reader->ins7E11[0x01]) // the position of the ins7E is taken from v13 log
898 uint8_t ins742b[5] = { 0xD0, 0x74, 0x2b, 0x00, 0x00 };
899 l = read_cmd_len(reader, ins742b); // get command len for ins742b
901 if(l < 2)
903 rdr_log(reader, "No TA1 change for this card is possible by ins7E11");
905 else
907 ins742b[4] = l;
908 bool ta1ok = 0;
909 if(!write_cmd_vg(ins742b, NULL) || !status_ok(cta_res + ins742b[4])) // get supported TA1 bytes
911 rdr_log(reader, "classD0 ins742b: failed");
912 return ERROR;
914 else
916 int32_t i;
917 for(i = 2; i < l; i++)
919 if(cta_res[i] == reader->ins7E11[0x00])
921 ta1ok = 1;
922 break;
927 if(ta1ok == 0)
929 rdr_log(reader, "The value %02X of ins7E11 is not supported,try one between %02X and %02X",
930 reader->ins7E11[0x00], cta_res[2], cta_res[ins742b[4] - 1]);
932 else
934 static const uint8_t ins7E11[5] = { 0xD0, 0x7E, 0x11, 0x00, 0x01 };
935 reader->ins7e11_fast_reset = 0;
936 l = do_cmd(reader, ins7E11, reader->ins7E11, NULL, cta_res);
938 if(l < 0 || !status_ok(cta_res))
940 rdr_log(reader, "classD0 ins7E11: failed");
941 return ERROR;
943 else
945 uint8_t TA1;
946 if(ATR_GetInterfaceByte(newatr, 1, ATR_INTERFACE_BYTE_TA, &TA1) == ATR_OK)
948 if(TA1 != reader->ins7E11[0x00])
950 rdr_log(reader, "classD0 ins7E11: Scheduling card reset for TA1 change from %02X to %02X", TA1, reader->ins7E11[0x00]);
951 reader->ins7e11_fast_reset = 1;
953 #if defined(WITH_COOLAPI) || defined(WITH_COOLAPI2)
954 if(reader->typ == R_MOUSE || reader->typ == R_SC8in1 || reader->typ == R_SMART || reader->typ == R_INTERNAL)
956 #else
957 if(reader->typ == R_MOUSE || reader->typ == R_SC8in1 || reader->typ == R_SMART)
959 #endif
960 add_job(reader->client, ACTION_READER_RESET_FAST, NULL, 0);
962 else
964 add_job(reader->client, ACTION_READER_RESTART, NULL, 0);
966 return OK; // Skip the rest of the init since the card will be reset anyway
974 //int16_t int32_t SWIRDstatus = cta_res[1];
975 static const uint8_t ins58[5] = { 0xD0, 0x58, 0x00, 0x00, 0x00 };
976 l = do_cmd(reader, ins58, NULL, NULL, cta_res);
978 if(l < 0)
980 rdr_log(reader, "classD0 ins58: failed");
981 return ERROR;
984 memset(reader->hexserial, 0, 8);
985 memcpy(reader->hexserial + 2, cta_res + 3, 4);
986 memcpy(reader->sa, cta_res + 3, 3);
987 reader->caid = cta_res[24] * 0x100 + cta_res[25];
988 reader->VgFuse = cta_res[2];
989 rdr_log(reader, "FuseByte: %02X", reader->VgFuse);
990 memset(reader->VgRegionC, 0, 8);
991 memcpy(reader->VgRegionC, cta_res + 60, 8);
993 rdr_log(reader, "Region Code: %c%c%c%c%c%c%c%c",
994 reader->VgRegionC[0], reader->VgRegionC[1],
995 reader->VgRegionC[2], reader->VgRegionC[3],
996 reader->VgRegionC[4], reader->VgRegionC[5],
997 reader->VgRegionC[6], reader->VgRegionC[7]);
999 memset(reader->VgCountryC, 0, 3);
1000 memcpy(reader->VgCountryC, cta_res + 55, 3);
1001 rdr_log(reader, "Country Code: %c%c%c", reader->VgCountryC[0], reader->VgCountryC[1], reader->VgCountryC[2]);
1003 // we have one provider, 0x0000
1004 reader->nprov = 1;
1005 memset(reader->prid, 0x00, sizeof(reader->prid));
1007 cCamCryptVG_SetSeed(reader);
1009 static const uint8_t insB4[5] = { 0xD0, 0xB4, 0x00, 0x00, 0x40 };
1010 uint16_t tbuff[32];
1011 cCamCryptVG_GetCamKey(reader, tbuff);
1012 l = do_cmd(reader, insB4, (uint8_t *)tbuff, NULL, cta_res);
1013 if(l < 0 || !status_ok(cta_res))
1015 rdr_log(reader, "classD0 insB4: failed");
1016 return ERROR;
1019 static const uint8_t insBC[5] = { 0xD0, 0xBC, 0x00, 0x00, 0x00 };
1020 l = do_cmd(reader, insBC, NULL, NULL, cta_res);
1021 if(l < 0)
1023 rdr_log(reader, "classD0 insBC: failed");
1024 return ERROR;
1027 // Class D1/D3 instructions only work after this point
1029 static const uint8_t insBE[5] = { 0xD3, 0xBE, 0x00, 0x00, 0x00 };
1030 l = do_cmd(reader, insBE, NULL, NULL, cta_res);
1031 if(l < 0)
1033 rdr_log(reader, "classD3 insBE: failed");
1034 return ERROR;
1037 static const uint8_t ins58a[5] = { 0xD1, 0x58, 0x00, 0x00, 0x00 };
1038 l = do_cmd(reader, ins58a, NULL, NULL, cta_res);
1039 if(l < 0)
1041 rdr_log(reader, "classD1 ins58: failed");
1042 return ERROR;
1045 int d37423_ok = 0;
1046 static const uint8_t ins7403[5] = { 0xD1, 0x74, 0x03, 0x00, 0x00 }; // taken from v13 boot log
1047 if(do_cmd(reader, ins7403, NULL, NULL, cta_res) < 0)
1049 rdr_log(reader, "classD1 ins7403: failed");
1051 else
1053 d37423_ok = (cta_res[2] >> 5) & 1;
1056 // new ins74 present at boot
1057 if(d37423_ok) // from ins7403 answer
1059 static const uint8_t ins7423[5] = { 0xD3, 0x74, 0x23, 0x00, 0x00 };
1060 if(do_cmd(reader, ins7423, NULL, NULL, cta_res) < 0)
1062 rdr_log(reader, "classD1 ins7423: failed");
1066 static const uint8_t ins742A[5] = { 0xD0, 0x74, 0x2A, 0x00, 0x00 };
1067 if(do_cmd(reader, ins742A, NULL, NULL, cta_res) < 0)
1069 rdr_log(reader, "classD0 ins742A: failed");
1072 static const uint8_t ins741B[5] = { 0xD1, 0x74, 0x1B, 0x00, 0x00 };
1073 if(do_cmd(reader, ins741B, NULL, NULL, cta_res) < 0)
1075 rdr_log(reader, "classD1 ins741B: failed");
1078 static const uint8_t ins4Ca[5] = { 0xD1, 0x4C, 0x00, 0x00, 0x00 };
1080 payload4C[4] = 0x83;
1082 l = do_cmd(reader, ins4Ca, payload4C, NULL, cta_res);
1083 if(l < 0 || !status_ok(cta_res))
1085 rdr_log(reader, "classD1 ins4Ca: failed");
1086 return ERROR;
1088 memcpy(reader->payload4C, payload4C, 0xF);
1090 if(reader->ins7E[0x1A])
1092 static const uint8_t ins7E[5] = { 0xD1, 0x7E, 0x10, 0x00, 0x1A };
1093 l = do_cmd(reader, ins7E, reader->ins7E, NULL, cta_res);
1094 if(l < 0 || !status_ok(cta_res))
1096 rdr_log(reader, "classD1 ins7E: failed");
1097 return ERROR;
1101 if(reader->ins42[0x25])
1103 static const uint8_t ins42[5] = { 0xD1, 0x42, 0x00, 0x00, 0x25 };
1104 l = do_cmd(reader, ins42, reader->ins42, NULL, cta_res);
1105 if(l < 0 || !status_ok(cta_res))
1107 rdr_log(reader, "classD1 ins42: failed");
1108 return ERROR;
1112 // get PIN settings
1113 static const uint8_t ins7411[5] = { 0xD3, 0x74, 0x11, 0x00, 0x00 };
1114 uint8_t payload2e4[4];
1115 uint8_t rbuff[264];
1116 if(do_cmd(reader, ins7411, NULL, rbuff, cta_res) < 0)
1118 rdr_log(reader, "classD3 ins7411: unable to get PIN");
1119 return ERROR;
1121 else
1123 memset(payload2e4, 0, 4);
1124 memcpy(payload2e4, rbuff + 7, 4);
1125 reader->VgPin = (rbuff[9] << 8) + rbuff[10];
1126 rdr_log(reader, "Pincode read: %04hu", reader->VgPin);
1129 // get PCB(content rating) settings
1130 static const uint8_t ins74e[5] = { 0xD1, 0x74, 0x0E, 0x00, 0x00 };
1131 if(do_cmd(reader, ins74e, NULL, NULL, cta_res) < 0)
1133 rdr_log(reader, "classD1 ins74e: failed to get PCB settings");
1135 else
1137 rdr_log(reader, "PCB settings: %X %X %X %X", cta_res[2], cta_res[3], cta_res[4], cta_res[5]);
1140 // send PIN
1141 static const uint8_t ins2epin[5] = { 0xD1, 0x2E, 0x04, 0x00, 0x04 };
1142 if(cfg.ulparent)
1144 l = do_cmd(reader, ins2epin, payload2e4, NULL, cta_res);
1145 if(l < 0 || !status_ok(cta_res))
1147 rdr_log(reader, "classD1 ins2E: failed");
1148 rdr_log(reader, "Cannot disable parental control");
1149 return ERROR;
1151 else
1153 rdr_log(reader, "Parental control disabled");
1157 // send check control for pin, needed on some cards
1158 // the presence and the value of payloads is provider's dependent*/
1159 if(reader->ins2e06[4])
1161 static const uint8_t ins2e06[5] = { 0xD1, 0x2E, 0x06, 0x00, 0x04 };
1162 l = do_cmd(reader, ins2e06, reader->ins2e06, NULL, cta_res);
1163 if(l < 0 || !status_ok(cta_res))
1165 rdr_log(reader, "classD1 ins2E: failed");
1166 return ERROR;
1170 // fix for 09ac cards
1171 uint8_t dimeno_magic[0x10] = { 0xF9, 0xFB, 0xCD, 0x5A, 0x76, 0xB5, 0xC4, 0x5C, 0xC8, 0x2E, 0x1D, 0xE1, 0xCC, 0x5B, 0x6B, 0x02 };
1172 int32_t a;
1173 for(a = 0; a < 4; a++)
1175 dimeno_magic[a] = dimeno_magic[a] ^ boxID[a];
1177 AES_set_decrypt_key(dimeno_magic, 128, &(csystem_data->astrokey));
1179 rdr_log(reader, "type: %s, caid: %04X", csystem_data->card_desc, reader->caid);
1180 rdr_log_sensitive(reader, "serial: {%02X%02X%02X%02X}, BoxID: {%02X%02X%02X%02X}, baseyear: %i",
1181 reader->hexserial[2],
1182 reader->hexserial[3],
1183 reader->hexserial[4],
1184 reader->hexserial[5],
1185 boxID[0],
1186 boxID[1],
1187 boxID[2],
1188 boxID[3],
1189 csystem_data->card_baseyear);
1191 rdr_log(reader, "ready for requests");
1193 return OK;
1196 static int32_t videoguard2_do_ecm(struct s_reader *reader, const ECM_REQUEST *er, struct s_ecm_answer *ea)
1198 uint8_t cta_res[CTA_RES_LEN];
1199 uint8_t ins40[5] = { 0xD1, 0x40, 0x60, 0x80, 0xFF };
1200 static const uint8_t ins54[5] = { 0xD3, 0x54, 0x00, 0x00, 0x00};
1201 int32_t posECMpart2 = er->ecm[6] + 7;
1202 int32_t lenECMpart2 = er->ecm[posECMpart2] + 1;
1203 uint8_t tbuff[264], rbuff[264];
1204 const uint8_t *EcmIrdHeader = er->ecm + 5;
1205 tbuff[0] = 0;
1207 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
1208 int32_t chk;
1209 chk = checksum_ok(EcmIrdHeader);
1211 if((er->ecm[3] != 0) || chk == 0 || (er->ecm[4] != 0 && 4 != er->ecm[2]- er->ecm[4]))
1213 rdr_log(reader, "Not a valid ecm");
1214 return E_CORRUPT;
1216 memcpy(tbuff + 1, er->ecm + posECMpart2 + 1, lenECMpart2 - 1);
1218 int32_t new_len = lenECMpart2;
1219 if(reader->fix_9993 && reader->caid == 0x919 && tbuff[1] == 0x7F)
1221 tbuff[1] = 0x47;
1222 tbuff[2] = 0x08;
1223 memmove(tbuff + 11, tbuff + 13, new_len - 11);
1224 new_len -= 2;
1227 ins40[4] = new_len;
1228 int32_t l;
1229 l = do_cmd(reader, ins40, tbuff, NULL, cta_res);
1231 if(l < 0 || !status_ok(cta_res))
1233 rdr_log(reader, "classD1 ins40: (%d) status not ok %02x %02x", l, cta_res[0], cta_res[1]);
1234 rdr_log(reader, "The card is not answering correctly! Restarting reader for safety");
1235 add_job(reader->client, ACTION_READER_RESTART, NULL, 0);
1236 return ERROR;
1238 else
1240 l = do_cmd(reader, ins54, NULL, rbuff, cta_res);
1241 if(l < 0 || !status_ok(cta_res + l))
1243 rdr_log(reader, "classD3 ins54: (%d) status not ok %02x %02x", l, cta_res[0], cta_res[1]);
1244 rdr_log(reader, "The card is not answering correctly! Restarting reader for safety");
1245 add_job(reader->client, ACTION_READER_RESTART, NULL, 0);
1246 return ERROR;
1248 else
1250 struct videoguard_data *csystem_data = reader->csystem_data;
1251 uint8_t *payload = rbuff + 5;
1252 uint8_t buff_0F[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1253 uint8_t buff_56[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1254 uint8_t buff_55[1] = { 0x00 };
1255 uint8_t tag, t_len;
1256 uint8_t *t_body;
1257 int32_t payloadLen = rbuff[4];
1258 int32_t ind = 8 + 6; // +8 (CW1), +2 (cw checksum) + 2 (tier used) +2 (result byte)
1260 while(ind < payloadLen)
1262 tag = payload[ind];
1263 t_len = payload[ind + 1]; // len of the tag
1264 t_body = payload + ind + 2; // body of the tag
1266 switch(tag)
1268 case 0x0F: // Debug ecm info
1269 if(t_len > 6)
1271 t_len = 6;
1273 memcpy(buff_0F, t_body, t_len);
1274 break;
1276 case 0x25: // CW2 tag
1277 memcpy(ea->cw + 8, t_body +1, 8);
1278 break;
1280 case 0x55: // cw crypt info tag
1281 memcpy(buff_55, t_body, 1 );
1282 break;
1284 case 0x56: // tag data for aes
1285 memcpy(buff_56, t_body, 8);
1286 break;
1288 default:
1289 break;
1291 ind += t_len + 2;
1294 if(12 < payloadLen)
1296 ea->tier = b2i(2, &payload[10]);
1299 memcpy(reader->VgLastPayload, buff_0F, 6);
1301 int32_t test_0F = 1;
1302 if(!cw_is_valid(rbuff + 5)) // sky cards report 90 00 = ok but send cw = 00 when something goes wrong :(
1304 if(buff_0F[0] & 1) // case 0f_0x 01 xx xx xx xx xx
1306 rdr_log(reader, "classD3 ins54: no cw --> Bad/wrong ECM");
1307 return E_CORRUPT;
1310 if(buff_0F[1] & 1) // case 0f_0x xx 01 xx xx xx xx
1312 rdr_log(reader, "classD3 ins54: no cw --> Card appears in error");
1313 test_0F = 0;
1316 if((buff_0F[0] >> 1) & 1) // case 0f_0x 02 xx xx xx xx xx
1318 rdr_log(reader, "classD3 ins54: no cw --> Card isn't active");
1319 test_0F = 0;
1321 else // These Messages are only necessary if the Card is active
1323 if((buff_0F[1] >> 4) & 1) // case 0f_0x xx 10 xx xx xx xx
1325 rdr_log(reader, "classD3 ins54: no cw --> Card needs pairing/extra data");
1326 if((reader->caid == 0x98C || reader->caid == 0x98D) && (buff_0F[5] == 0)){ //case 0f_0x xx 10 xx xx xx 00
1327 rdr_log(reader, "classD3 ins54: no cw --> unassigned Boxid");
1329 test_0F = 0;
1332 if((buff_0F[1] >> 5) & 1) // case 0f_0x xx 20 xx xx xx xx
1334 rdr_log(reader, "classD3 ins54: no cw --> No tier found"); //check this
1335 test_0F = 0;
1338 if((buff_0F[2] >> 5) & 1) // case 0f_0x xx xx 20 xx xx xx
1340 rdr_log(reader, "classD3 ins54: no cw --> Tier expired");
1341 test_0F = 0;
1344 if((buff_0F[1] >> 6) & 1) // case 0f_0x xx 40 xx xx xx xx
1346 rdr_log(reader, "classD3 ins54: no cw --> Card needs pin");
1347 test_0F = 0;
1350 if((reader->caid == 0x98C || reader->caid == 0x98D) && ((buff_0F[5] >> 3) & 1)) //case 0f_0x xx xx xx xx xx XX = binary xxxx1xxx
1352 rdr_log(reader, "classD3 ins54: no cw --> CW-overcrypt%s is required! (Debug-ECM-Info: 0F_06 %02X %02X %02X %02X %02X %02X)",
1353 (((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
1357 if(test_0F) // case unknown error
1359 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",
1360 buff_0F[0], buff_0F[1], buff_0F[2], buff_0F[3], buff_0F[4], buff_0F[5]);
1362 return ERROR;
1365 // copy cw1 in place
1366 memcpy(ea->cw + 0, rbuff + 5, 8);
1368 //case 55_01 xx where bit3==1, bit2==0, bit1==0, and bit0==1, ins7e and CW-Overcrypt may not required
1369 if(((buff_55[0] >> 3) & 1) && (~((buff_55[0] >> 2) & 1)) && (~((buff_55[0] >> 1) & 1)) && (buff_55[0] & 1))
1371 rdr_log_dbg(reader, D_READER, "classD3 ins54: Tag55_01 = %02X, ins7e and CW-overcrypt may not required", buff_55[0]);
1374 // case 55_01 xx where bit0==1, CW is crypted
1375 if(buff_55[0] & 1)
1377 if(~((buff_55[0] >> 2) & 1)) //case 55_01 xx where bit2==0
1379 if((buff_55[0] >> 1) & 1) //case 55_01 xx where bit1==1, unique Pairing
1381 rdr_log_dbg(reader, D_READER, "classD3 ins54: CW is crypted, trying to decrypt unique pairing mode 0x%02X", buff_55[0]);
1382 if((buff_56[0]|buff_56[1]|buff_56[2]|buff_56[3]|buff_56[4]|buff_56[5]|buff_56[6]|buff_56[7]) != 0) { //when 56_08 is non-zero use AES
1383 rdr_log_dbg(reader, D_READER, "encrypted AES buffer is: %02X%02X%02X%02X%02X%02X%02X%02X%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], buff_56[0], buff_56[1], buff_56[2], buff_56[3], buff_56[4], buff_56[5], buff_56[6], buff_56[7]);
1384 uint8_t aesbuf[0x10];
1385 uint8_t keybuf[0x10];
1386 AES_KEY aeskey;
1387 memcpy(aesbuf, rbuff + 5, 8);
1388 memcpy(aesbuf + 8, buff_56, 8);
1389 memcpy(keybuf, &(reader->k1_unique), 16);
1390 if(reader->k1_unique[16] == 0x10) {
1391 rdr_log_dbg(reader, D_READER, "use k1(AES) for AES buffer decryption in unique pairing mode");
1392 AES_set_decrypt_key(keybuf, 128, &aeskey);
1393 AES_decrypt(aesbuf, aesbuf, &aeskey);
1394 if(er->ecm[0] & 1){ //log decrypted CW
1395 rdr_log_dbg(reader, D_READER, "decrypted CW is: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", aesbuf[8], aesbuf[9], aesbuf[10], aesbuf[11], aesbuf[12], aesbuf[13], aesbuf[14], aesbuf[15], aesbuf[0], aesbuf[1], aesbuf[2], aesbuf[3], aesbuf[4], aesbuf[5], aesbuf[6], aesbuf[7]);
1396 } else {
1397 rdr_log_dbg(reader, D_READER, "decrypted CW is: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", aesbuf[0], aesbuf[1], aesbuf[2], aesbuf[3], aesbuf[4], aesbuf[5], aesbuf[6], aesbuf[7], aesbuf[8], aesbuf[9], aesbuf[10], aesbuf[11], aesbuf[12], aesbuf[13], aesbuf[14], aesbuf[15]);
1399 memcpy(ea->cw + 0, aesbuf, 8);
1401 else {
1402 rdr_log_dbg(reader, D_READER, "k1 for unique pairing mode is not set correctly");
1403 return ERROR;
1406 else { //case 56_08 is zero, DES or 3DES
1407 if(er->ecm[0] & 1){ //log crypted CW
1408 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]);
1409 } else {
1410 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]);
1412 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
1414 if(reader->k1_unique[16] == 0x08){
1415 rdr_log_dbg(reader, D_READER, "use k1(DES) for CW decryption in unique pairing mode");
1416 des_ecb_decrypt(ea->cw, reader->k1_unique, 0x08);
1418 else
1420 rdr_log_dbg(reader, D_READER, "use k1(3DES) for CW decryption in unique pairing mode");
1421 des_ecb3_decrypt(ea->cw, reader->k1_unique);
1423 if(er->ecm[0] & 1){ //log decrypted CW
1424 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]);
1425 } else {
1426 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]);
1429 else
1431 rdr_log_dbg(reader, D_READER, "k1 for unique pairing mode is not set");
1432 return ERROR;
1436 else //case 55_01 xx where bit1==0, generic Pairing
1438 rdr_log_dbg(reader, D_READER, "classD3 ins54: CW is crypted, trying to decrypt generic pairing mode 0x%02X", buff_55[0]);
1439 if((buff_56[0]|buff_56[1]|buff_56[2]|buff_56[3]|buff_56[4]|buff_56[5]|buff_56[6]|buff_56[7]) != 0) { //when 56_08 is non-zero use AES
1440 rdr_log_dbg(reader, D_READER, "encrypted AES buffer is: %02X%02X%02X%02X%02X%02X%02X%02X%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], buff_56[0], buff_56[1], buff_56[2], buff_56[3], buff_56[4], buff_56[5], buff_56[6], buff_56[7]);
1441 uint8_t aesbuf[0x10];
1442 uint8_t keybuf[0x10];
1443 AES_KEY aeskey;
1444 memcpy(aesbuf, rbuff + 5, 8);
1445 memcpy(aesbuf + 8, buff_56, 8);
1446 memcpy(keybuf, &(reader->k1_generic), 16);
1447 if(reader->k1_generic[16] == 0x10) {
1448 rdr_log_dbg(reader, D_READER, "use k1(AES) for AES buffer decryption in generic pairing mode");
1449 AES_set_decrypt_key(keybuf, 128, &aeskey);
1450 AES_decrypt(aesbuf, aesbuf, &aeskey);
1451 if(er->ecm[0] & 1){ //log decrypted CW
1452 rdr_log_dbg(reader, D_READER, "decrypted CW is: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", aesbuf[8], aesbuf[9], aesbuf[10], aesbuf[11], aesbuf[12], aesbuf[13], aesbuf[14], aesbuf[15], aesbuf[0], aesbuf[1], aesbuf[2], aesbuf[3], aesbuf[4], aesbuf[5], aesbuf[6], aesbuf[7]);
1453 } else {
1454 rdr_log_dbg(reader, D_READER, "decrypted CW is: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", aesbuf[0], aesbuf[1], aesbuf[2], aesbuf[3], aesbuf[4], aesbuf[5], aesbuf[6], aesbuf[7], aesbuf[8], aesbuf[9], aesbuf[10], aesbuf[11], aesbuf[12], aesbuf[13], aesbuf[14], aesbuf[15]);
1456 memcpy(ea->cw + 0, aesbuf, 8);
1458 else {
1459 rdr_log_dbg(reader, D_READER, "k1 for generic pairing mode is not set correctly");
1460 return ERROR;
1463 else { // case 56_08 is zero, DES or 3DES
1464 if(er->ecm[0] & 1){ //log crypted CW
1465 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]);
1466 } else {
1467 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]);
1469 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
1471 if(reader->k1_generic[16] == 0x08){
1472 rdr_log_dbg(reader, D_READER, "use k1(DES) for CW decryption in generic pairing mode");
1473 des_ecb_decrypt(ea->cw, reader->k1_generic, 0x08);
1475 else
1477 rdr_log_dbg(reader, D_READER, "use k1(3DES) for CW decryption in generic pairing mode");
1478 des_ecb3_decrypt(ea->cw, reader->k1_generic);
1480 if(er->ecm[0] & 1){ //log decrypted CW
1481 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]);
1482 } else {
1483 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]);
1486 else
1488 rdr_log_dbg(reader, D_READER, "k1 for generic pairing mode is not set");
1489 return ERROR;
1494 else //unknown pairing mode
1496 rdr_log_dbg(reader, D_READER, "classD3 ins54: CW is crypted, unknown pairing mode 0x%02X", buff_55[0]);
1497 if(er->ecm[0] & 1){ //log crypted CW
1498 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]);
1499 } else {
1500 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]);
1502 return ERROR;
1506 // case 55_01 xx where bit2==1, old dimeno_PostProcess_Decrypt(reader, rbuff, ea->cw);
1507 if((buff_55[0] >> 2) & 1)
1509 rdr_log_dbg(reader, D_READER, "classD3 ins54: CW is crypted, trying to decrypt AES boxkey mode 0x%02X", buff_55[0]);
1510 rdr_log_dbg(reader, D_READER, "encrypted AES buffer is: %02X%02X%02X%02X%02X%02X%02X%02X%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], buff_56[0], buff_56[1], buff_56[2], buff_56[3], buff_56[4], buff_56[5], buff_56[6], buff_56[7]);
1511 uint8_t aesbuf[0x10];
1512 memcpy(aesbuf, rbuff + 5, 8);
1513 memcpy(aesbuf + 8, buff_56, 8);
1514 rdr_log_dbg(reader, D_READER, "use dimeno magic for AES buffer decryption");
1515 AES_decrypt(aesbuf, aesbuf, &(csystem_data->astrokey));
1516 if(er->ecm[0] & 1){ //log decrypted CW
1517 rdr_log_dbg(reader, D_READER, "decrypted CW is: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", aesbuf[8], aesbuf[9], aesbuf[10], aesbuf[11], aesbuf[12], aesbuf[13], aesbuf[14], aesbuf[15], aesbuf[0], aesbuf[1], aesbuf[2], aesbuf[3], aesbuf[4], aesbuf[5], aesbuf[6], aesbuf[7]);
1518 } else {
1519 rdr_log_dbg(reader, D_READER, "decrypted CW is: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", aesbuf[0], aesbuf[1], aesbuf[2], aesbuf[3], aesbuf[4], aesbuf[5], aesbuf[6], aesbuf[7], aesbuf[8], aesbuf[9], aesbuf[10], aesbuf[11], aesbuf[12], aesbuf[13], aesbuf[14], aesbuf[15]);
1521 memcpy(ea->cw + 0, aesbuf, 8); // copy calculated CW in right place
1524 if(new_len != lenECMpart2)
1526 memcpy(ea->cw, ea->cw + 8, 8);
1527 memset(ea->cw + 8, 0, 8);
1530 // test for postprocessing marker
1531 int32_t posB0 = -1;
1532 int32_t i;
1533 for(i = 6; i < posECMpart2; i++)
1535 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)))
1537 posB0 = i;
1538 break;
1542 if(posB0 != -1 && (reader->caid == 0x919 || reader->caid == 0x93B || reader->caid == 0x9CD || reader->caid == 0x9C1))
1544 do_post_dw_hash(reader, ea->cw + 0, &er->ecm[posB0 - 2]);
1545 do_post_dw_hash(reader, ea->cw + 8, &er->ecm[posB0 - 2]);
1548 if(reader->caid == 0x0907) // quickfix: cw2 is not a valid cw, something went wrong before
1550 memset(ea->cw + 8, 0, 8);
1551 if(er->ecm[0] & 1)
1553 memcpy(ea->cw + 8, ea->cw, 8);
1554 memset(ea->cw, 0, 8);
1557 else
1559 if(er->ecm[0] & 1)
1561 uint8_t tmpcw[8];
1562 memcpy(tmpcw, ea->cw + 8, 8);
1563 memcpy(ea->cw + 8, ea->cw + 0, 8);
1564 memcpy(ea->cw + 0, tmpcw, 8);
1568 return OK;
1573 static int32_t videoguard2_do_emm(struct s_reader *reader, EMM_PACKET *ep)
1575 return videoguard_do_emm(reader, ep, 0xD1, vg2_read_tiers, do_cmd);
1578 static int32_t videoguard2_do_rawcmd(struct s_reader *reader, CMD_PACKET *cp)
1580 return videoguard_do_rawcmd(reader, cp);
1583 static int32_t videoguard2_card_info(struct s_reader *reader)
1585 // info is displayed in init, or when processing info
1586 struct videoguard_data *csystem_data = reader->csystem_data;
1587 rdr_log(reader, "card detected");
1588 rdr_log(reader, "type: %s", csystem_data->card_desc);
1590 if(reader->ins7e11_fast_reset != 1)
1592 vg2_read_tiers(reader);
1594 return OK;
1597 static void videoguard2_card_done(struct s_reader *reader)
1599 struct videoguard_data *csystem_data = reader->csystem_data;
1600 if(csystem_data)
1602 NULLFREE(csystem_data->cmd_table);
1606 const struct s_cardsystem reader_videoguard2 =
1608 .desc = "videoguard2",
1609 .caids = (uint16_t[]){ 0x09, 0 },
1610 .do_emm = videoguard2_do_emm,
1611 .do_rawcmd = videoguard2_do_rawcmd,
1612 .do_ecm = videoguard2_do_ecm,
1613 .card_info = videoguard2_card_info,
1614 .card_init = videoguard2_card_init,
1615 .poll_status = videoguard2_poll_status,
1616 .card_done = videoguard2_card_done,
1617 .get_emm_type = videoguard_get_emm_type,
1618 .get_emm_filter = videoguard_get_emm_filter,
1621 #endif