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