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
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;
165 switch(ecm_header_data
[ecmi
+ 2])
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)
181 hk
[0] = ((hk
[3] & hk
[5]) | ((~hk
[5]) & hk
[4]));
185 hk
[0] = ((hk
[3] & hk
[4]) | ((~hk
[3]) & hk
[5]));
190 hk
[0] = (hk
[0] + ((cw
[j
+ 1] << 8) | cw
[j
]));
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)));
205 hk
[7] = hk
[2] + (((hk
[0] << Hash4
[m
& 0xF]) | (hk
[0] >> (0x10 - Hash4
[m
& 0xF]))));
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:");
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:");
240 //memcpy(DW_OUTPUT, DW_INPUT, 8);
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");
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
);
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",
313 timeinfo
.tm_year
+ 1900,
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",
329 timeinfo
.tm_year
+ 1900,
335 get_tiername(tier_id
, reader
->caid
, tiername
));
342 rdr_log(reader
, "------------------------------------------------------from-ins70--");
344 else if(reader
->readtiers
== 2)
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");
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");
368 int32_t num
= cta_res
[1];
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;
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
))
390 if(cta_res
[2] == 0 && cta_res
[3] == 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
++)
408 l
= do_cmd(reader
, ins76
, NULL
, NULL
, cta_res
);
410 if(l
< 0 || !status_ok(cta_res
+ l
))
415 if(cta_res
[2] == 0 && cta_res
[3] == 0 && stopemptytier
)
420 if(cta_res
[2] != 0 || cta_res
[3] != 0)
423 uint16_t tier_id
= (cta_res
[2] << 8) | cta_res
[3];
424 // add entitlements to list
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);
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",
437 timeinfo
.tm_year
+ 1900,
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);
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
];
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");
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");
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");
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");
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");
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
++)
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");
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");
613 case 0x00: // normal state
620 rdr_log(reader
, "unknown ins5C state: %02X %02X %02X %02X",
621 cta_res
[0], cta_res
[1], cta_res
[2], cta_res
[3]);
626 reader
->last_poll
= now
;
630 static int32_t videoguard2_card_init(struct s_reader
*reader
, ATR
*newatr
)
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");
638 rdr_log_dbg(reader
, D_READER
, "passed history check");
643 if(!cs_malloc(&reader
->csystem_data
, sizeof(struct videoguard_data
)))
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 */
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 };
671 if((l
= read_cmd_len(reader
, ins7401
)) < 0) // not a videoguard2/NDS card or communication error
677 if(!write_cmd_vg(ins7401
, NULL
) || !status_ok(cta_res
+ l
))
679 rdr_log(reader
, "classD0 ins7401: failed - cmd list not read");
683 memorize_cmd_table(reader
, cta_res
, l
);
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.");
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
]))
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
722 if(!write_cmd_vg(ins7404
, NULL
) || !status_ok(cta_res
+ l
))
724 rdr_log(reader
, "classD0 ins7404: failed");
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
);
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");
749 if(reader
->boxid
> 0)
751 // the boxid is specified in the config
753 for(i
= 0; i
< 4; i
++)
755 boxID
[i
] = (reader
->boxid
>> (8 * (3 - i
))) % 0x100;
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
765 l
= read_cmd_len(reader
, ins36
);
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");
778 ins36
[3] = cta_res
[0];
779 ins36
[4] = cta_res
[1];
784 if(!write_cmd_vg(ins36
, NULL
) || !status_ok(cta_res
+ l
))
786 rdr_log(reader
, "classD0 ins36: failed");
790 memcpy(buff
, ins36
, 5);
791 memcpy(buff
+ 5, cta_res
, l
);
792 memcpy(buff
+ 5 + l
, cta_res
+ l
, 2);
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");
804 // skipping the initial fixed fields: cmdecho (4) + length (1) + encr/rev++ (4)
809 if(!gotUA
&& buff
[i
] < 0xF0) // then we guess that the next 4 bytes is the UA
816 switch(buff
[i
]) // object length vary depending on type
818 case 0x00: // padding
822 case 0xEF: // card status
830 case 0xDF: // next server contact
835 memcpy(boxID
, buff
+ i
+ 1, sizeof(boxID
));
844 case 0x01: // date & time
853 case 0x67: // signature
856 case 0xE9: // tier dates
857 case 0xF8: // Old PPV Event Record
859 i
+= buff
[i
+ 1] + 2; // skip length + 2 bytes (type and length)
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;
872 rdr_log(reader
, "no boxID available");
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()
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");
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
903 rdr_log(reader
, "No TA1 change for this card is possible by ins7E11");
909 if(!write_cmd_vg(ins742b
, NULL
) || !status_ok(cta_res
+ ins742b
[4])) // get supported TA1 bytes
911 rdr_log(reader
, "classD0 ins742b: failed");
917 for(i
= 2; i
< l
; i
++)
919 if(cta_res
[i
] == reader
->ins7E11
[0x00])
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]);
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");
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
)
957 if(reader
->typ
== R_MOUSE
|| reader
->typ
== R_SC8in1
|| reader
->typ
== R_SMART
)
960 add_job(reader
->client
, ACTION_READER_RESET_FAST
, NULL
, 0);
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
);
980 rdr_log(reader
, "classD0 ins58: failed");
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
1005 memset(reader
->prid
, 0x00, sizeof(reader
->prid
));
1007 cCamCryptVG_SetSeed(reader
);
1009 static const uint8_t insB4
[5] = { 0xD0, 0xB4, 0x00, 0x00, 0x40 };
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");
1019 static const uint8_t insBC
[5] = { 0xD0, 0xBC, 0x00, 0x00, 0x00 };
1020 l
= do_cmd(reader
, insBC
, NULL
, NULL
, cta_res
);
1023 rdr_log(reader
, "classD0 insBC: failed");
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
);
1033 rdr_log(reader
, "classD3 insBE: failed");
1037 static const uint8_t ins58a
[5] = { 0xD1, 0x58, 0x00, 0x00, 0x00 };
1038 l
= do_cmd(reader
, ins58a
, NULL
, NULL
, cta_res
);
1041 rdr_log(reader
, "classD1 ins58: failed");
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");
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");
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");
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");
1113 static const uint8_t ins7411
[5] = { 0xD3, 0x74, 0x11, 0x00, 0x00 };
1114 uint8_t payload2e4
[4];
1116 if(do_cmd(reader
, ins7411
, NULL
, rbuff
, cta_res
) < 0)
1118 rdr_log(reader
, "classD3 ins7411: unable to get PIN");
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");
1137 rdr_log(reader
, "PCB settings: %X %X %X %X", cta_res
[2], cta_res
[3], cta_res
[4], cta_res
[5]);
1141 static const uint8_t ins2epin
[5] = { 0xD1, 0x2E, 0x04, 0x00, 0x04 };
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");
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");
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 };
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],
1189 csystem_data
->card_baseyear
);
1191 rdr_log(reader
, "ready for requests");
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;
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
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");
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)
1223 memmove(tbuff
+ 11, tbuff
+ 13, new_len
- 11);
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);
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);
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 };
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
)
1263 t_len
= payload
[ind
+ 1]; // len of the tag
1264 t_body
= payload
+ ind
+ 2; // body of the tag
1268 case 0x0F: // Debug ecm info
1273 memcpy(buff_0F
, t_body
, t_len
);
1276 case 0x25: // CW2 tag
1277 memcpy(ea
->cw
+ 8, t_body
+1, 8);
1280 case 0x55: // cw crypt info tag
1281 memcpy(buff_55
, t_body
, 1 );
1284 case 0x56: // tag data for aes
1285 memcpy(buff_56
, t_body
, 8);
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");
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");
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");
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");
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
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");
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");
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]);
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
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];
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]);
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);
1402 rdr_log_dbg(reader
, D_READER
, "k1 for unique pairing mode is not set correctly");
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]);
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);
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]);
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]);
1431 rdr_log_dbg(reader
, D_READER
, "k1 for unique pairing mode is not set");
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];
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]);
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);
1459 rdr_log_dbg(reader
, D_READER
, "k1 for generic pairing mode is not set correctly");
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]);
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);
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]);
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]);
1488 rdr_log_dbg(reader
, D_READER
, "k1 for generic pairing mode is not set");
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]);
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]);
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]);
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
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)))
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);
1553 memcpy(ea
->cw
+ 8, ea
->cw
, 8);
1554 memset(ea
->cw
, 0, 8);
1562 memcpy(tmpcw
, ea
->cw
+ 8, 8);
1563 memcpy(ea
->cw
+ 8, ea
->cw
+ 0, 8);
1564 memcpy(ea
->cw
+ 0, tmpcw
, 8);
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
);
1597 static void videoguard2_card_done(struct s_reader
*reader
)
1599 struct videoguard_data
*csystem_data
= reader
->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
,