source: trunk/reader-viaccess.c

Last change on this file was 11636, checked in by bust3d, 23 months ago

Replace all strlen with safe strlen -> thanks @savan
https://board.streamboard.tv/forum/thread/47678-oscam-bug-report/?postID=599931#post599931

  • Property svn:eol-style set to LF
File size: 75.0 KB
Line 
1#include "globals.h"
2#ifdef READER_VIACCESS
3#include "oscam-aes.h"
4#include "oscam-time.h"
5#include "oscam-emm.h"
6#include "reader-common.h"
7#include "cscrypt/des.h"
8#include "oscam-work.h"
9
10struct geo_cache
11{
12 uint32_t provid;
13 uint8_t geo[256];
14 uint8_t geo_len;
15 int32_t number_ecm;
16};
17
18struct viaccess_data
19{
20 struct geo_cache last_geo;
21 uint8_t availkeys[CS_MAXPROV][16];
22};
23
24struct via_date
25{
26 uint16_t day_s : 5;
27 uint16_t month_s : 4;
28 uint16_t year_s : 7;
29
30 uint16_t day_e : 5;
31 uint16_t month_e : 4;
32 uint16_t year_e : 7;
33};
34
35static void parse_via_date(const uint8_t *buf, struct via_date *vd, int32_t fend)
36{
37 uint16_t date;
38
39 date = (buf[0] << 8) | buf[1];
40 vd->day_s = date & 0x1f;
41 vd->month_s = (date >> 5) & 0x0f;
42 vd->year_s = (date >> 9) & 0x7f;
43
44 if(fend)
45 {
46 date = (buf[2] << 8) | buf[3];
47 vd->day_e = date & 0x1f;
48 vd->month_e = (date >> 5) & 0x0f;
49 vd->year_e = (date >> 9) & 0x7f;
50 }
51}
52
53struct emm_rass *find_rabuf(struct s_client *client, int32_t provid, uint8_t nano, int8_t add)
54{
55 struct emm_rass *e;
56 LL_ITER it;
57
58 if(!client->ra_buf)
59 {
60 client->ra_buf = ll_create("client->ra_buf");
61 }
62
63 it = ll_iter_create(client->ra_buf);
64
65 while((e = ll_iter_next(&it)) != NULL)
66 {
67 if(!add && e->provid == provid && e->emmlen != 0)
68 {
69 return e;
70 }
71
72 if(add && e->provid == provid && e->emm[0] == nano)
73 {
74 return e;
75 }
76 }
77
78 if(!add)
79 {
80 return NULL;
81 }
82
83 if(!cs_malloc(&e, sizeof(struct emm_rass)))
84 {
85 return NULL;
86 }
87
88 e->provid = provid;
89 ll_append(client->ra_buf, e);
90 return e;
91}
92
93static void show_class(struct s_reader *reader, const char *p, uint32_t provid, const uint8_t *b, int32_t l)
94{
95 int32_t i, j;
96
97 // b -> via date (4 uint8_ts)
98 b += 4;
99 l -= 4;
100
101 j = l - 1;
102 for(; j >= 0; j--)
103 {
104 for(i = 0; i < 8; i++)
105 {
106 if(b[j] & (1 << (i & 7)))
107 {
108 uint8_t cls;
109 struct via_date vd;
110 parse_via_date(b - 4, &vd, 1);
111 cls = (l - (j + 1)) * 8 + i;
112
113 if(p) // just show class info, dont add entitlement!
114 {
115 rdr_log(reader, "%sclass: %02X, expiry date: %04d/%02d/%02d - %04d/%02d/%02d", p, cls,
116 vd.year_s + 1980, vd.month_s, vd.day_s,
117 vd.year_e + 1980, vd.month_e, vd.day_e);
118 }
119 else
120 {
121 rdr_log(reader, "class: %02X, expiry date: %04d/%02d/%02d - %04d/%02d/%02d", cls,
122 vd.year_s + 1980, vd.month_s, vd.day_s,
123 vd.year_e + 1980, vd.month_e, vd.day_e);
124
125 //convert time:
126 time_t start_t, end_t;
127 struct tm tm;
128 memset(&tm, 0, sizeof(tm));
129 tm.tm_year = vd.year_s + 80; //via year starts in 1980, tm_year starts in 1900
130 tm.tm_mon = vd.month_s - 1; // january is 0 in tm_mon
131 tm.tm_mday = vd.day_s;
132 start_t = cs_timegm(&tm);
133
134 tm.tm_year = vd.year_e + 80; //via year starts in 1980, tm_year starts in 1900
135 tm.tm_mon = vd.month_e - 1; // january is 0 in tm_mon
136 tm.tm_mday = vd.day_e;
137 end_t = cs_timegm(&tm);
138 cs_add_entitlement(reader, reader->caid, provid, cls, cls, start_t, end_t, 5, 1);
139 }
140 }
141 }
142 }
143}
144
145static int8_t add_find_class(struct s_reader *reader, uint32_t provid, const uint8_t *b, int32_t l, int8_t add)
146{
147 int32_t i, j, freshdate = 0;
148
149 // b -> via date (4 uint8_ts)
150 b += 4;
151 l -= 4;
152
153 j = l - 1;
154 for(; j >= 0; j--)
155 {
156 for(i = 0; i < 8; i++)
157 {
158 if(b[j] & (1 << (i & 7)))
159 {
160 uint8_t cls;
161 cls = (l - (j + 1)) * 8 + i;
162 if(cs_add_entitlement(reader, reader->caid, provid, cls, cls, 0, 0, 5, 0) == NULL && !add)
163 {
164 rdr_log(reader, "provid %06X class %02X not found", provid, cls);
165 freshdate = 1;
166 }
167 else
168 {
169 if(!add)
170 {
171 rdr_log(reader, "provid %06X has matching class %02X", provid, cls);
172 }
173 struct via_date vd;
174 parse_via_date(b - 4, &vd, 1);
175 time_t start_t, end_t;
176 struct tm tm;
177
178 //convert time:
179 memset(&tm, 0, sizeof(tm));
180 tm.tm_year = vd.year_s + 80; // via year starts in 1980, tm_year starts in 1900
181 tm.tm_mon = vd.month_s - 1; // january is 0 in tm_mon
182 tm.tm_mday = vd.day_s;
183 start_t = cs_timegm(&tm);
184
185 tm.tm_year = vd.year_e + 80; // via year starts in 1980, tm_year starts in 1900
186 tm.tm_mon = vd.month_e - 1; // january is 0 in tm_mon
187 tm.tm_mday = vd.day_e;
188 end_t = cs_timegm(&tm);
189
190 if(cs_add_entitlement(reader, reader->caid, provid, cls, cls, start_t, end_t, 5, add) != NULL)
191 {
192 if(!add)
193 {
194 rdr_log(reader, "class %02X provid %06X has already this daterange or newer entitled", cls, provid);
195 }
196 }
197 else
198 {
199 freshdate = 1;
200 }
201 }
202 }
203 }
204 }
205
206 if(freshdate == 0)
207 {
208 return -2;
209 }
210
211 return 1; // emmdate is fresh!
212}
213
214static void show_subs(struct s_reader *reader, const uint8_t *emm)
215{
216 switch(emm[0])
217 {
218 case 0xA9:
219 {
220 show_class(reader, "nano A9: ", 1, emm + 2, emm[1]);
221 break;
222 }
223
224 case 0xA6:
225 {
226 char szGeo[256];
227
228 memset(szGeo, 0, 256);
229 cs_strncpy(szGeo, (char *)emm + 2, emm[1]);
230 rdr_log(reader, "nano A6: geo %s", szGeo);
231 break;
232 }
233
234 case 0xB6:
235 {
236 uint8_t m; // modexp
237 struct via_date vd;
238
239 m = emm[emm[1] + 1];
240 parse_via_date(emm + 2, &vd, 0);
241 rdr_log(reader, "nano B6: modexp %d%d%d%d%d%d: %02d/%02d/%04d",
242 (m & 0x20) ? 1 : 0,
243 (m & 0x10) ? 1 : 0,
244 (m & 0x08) ? 1 : 0,
245 (m & 0x04) ? 1 : 0,
246 (m & 0x02) ? 1 : 0,
247 (m & 0x01) ? 1 : 0,
248 vd.day_s, vd.month_s, vd.year_s + 1980);
249 break;
250 }
251 }
252}
253
254static int32_t chk_prov(struct s_reader *reader, uint8_t *id, uint8_t keynr)
255{
256 struct viaccess_data *csystem_data = reader->csystem_data;
257 int32_t i, j, rc;
258
259 for(rc = i = 0; (!rc) && (i < reader->nprov); i++)
260 {
261 if(!memcmp(&reader->prid[i][1], id, 3))
262 {
263 for(j = 0; (!rc) && (j < 16); j++)
264 {
265 if(csystem_data->availkeys[i][j] == keynr)
266 {
267 rc = 1;
268 }
269 }
270 }
271 }
272 return (rc);
273}
274
275static int32_t get_maturity(struct s_reader *reader)
276{
277 /* retrieve maturity rating on the card */
278
279 def_resp;
280
281 uint8_t insac[] = { 0xca, 0xac, 0x00, 0x00, 0x00 }; // select data
282 uint8_t insb8[] = { 0xca, 0xb8, 0x00, 0x00, 0x00 }; // read selected data
283
284 insac[2] = 0x06;
285 write_cmd(insac, NULL); // request maturity rating
286
287 insb8[4] = 0x02;
288 write_cmd(insb8, NULL); // read maturity rating nano + len
289
290 insb8[4] = cta_res[1];
291 write_cmd(insb8, NULL); // read maturity rating
292
293 reader->maturity = cta_res[cta_lr - 3] & 0x0F;
294 if (reader->maturity < 0xF)
295 {
296 rdr_log(reader, "Maturity level [%X]= older than %i years", reader->maturity, reader->maturity);
297 }
298 else
299 {
300 rdr_log(reader, "Maturity level [%X]=no age limit", reader->maturity);
301 }
302 return 0;
303}
304
305static int32_t unlock_parental(struct s_reader *reader)
306{
307 /* disabling parental lock. assuming pin "0000" if no pin code is provided in the config */
308
309 static const uint8_t inDPL[] = { 0xca, 0x24, 0x02, 0x00, 0x09 };
310 uint8_t cmDPL[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F };
311 def_resp;
312
313 if(strcmp(reader->pincode, "none"))
314 {
315 rdr_log(reader, "Using PIN %s", reader->pincode);
316 // the pin need to be coded in bcd, so we need to convert from ascii to bcd, so '1234' -> 0x12 0x34
317 cmDPL[6] = ((reader->pincode[0] - 0x30) << 4) | ((reader->pincode[1] - 0x30) & 0x0f);
318 cmDPL[7] = ((reader->pincode[2] - 0x30) << 4) | ((reader->pincode[3] - 0x30) & 0x0f);
319 }
320 else
321 {
322 rdr_log(reader, "Using PIN 0000!");
323 }
324 write_cmd(inDPL, cmDPL);
325
326 if(!(cta_res[cta_lr - 2] == 0x90 && cta_res[cta_lr - 1] == 0))
327 {
328 if(strcmp(reader->pincode, "none"))
329 {
330 rdr_log(reader, "Can't disable parental lock. Wrong PIN? OSCam used %s!", reader->pincode);
331 }
332 else
333 {
334 rdr_log(reader, "Can't disable parental lock. Wrong PIN? OSCam used 0000!");
335 }
336 }
337 else
338 {
339 rdr_log(reader, "Parental lock disabled");
340 get_maturity(reader);
341 }
342
343 return 0;
344}
345
346int32_t hdSurEncBasicCrypt_D2_0F_11(int32_t Value, int32_t XorVal)
347{
348 int32_t i = (Value << 13) - Value + 0x1B59;
349 i = (i * Value) + 0x07CF;
350 return (i ^ XorVal);
351}
352
353int32_t hdSurEncCryptLookup_D2_0F_11(uint8_t Value, uint8_t AddrInd)
354{
355 static const uint8_t lookup[] =
356 {
357 0x94, 0xB2, 0xA9, 0x79, 0xC4, 0xC7, 0x0D, 0x36, 0x6F, 0x24, 0x11, 0xD1, 0xDB, 0x59, 0xD2, 0xA5,
358 0xE1, 0x00, 0xD4, 0x97, 0xA3, 0x2B, 0x11, 0xFA, 0x5F, 0xF1, 0xC1, 0x44, 0xBF, 0x9B, 0x5A, 0xC8,
359 0xF1, 0xE1, 0x99, 0x82, 0x0E, 0xB2, 0x01, 0x09, 0x0C, 0xC8, 0xB3, 0x3B, 0xD1, 0x80, 0x50, 0xE8,
360 0xF5, 0x52, 0x4C, 0xE6, 0x82, 0xAC, 0x58, 0x40, 0xD4, 0x71, 0x87, 0x52, 0x06, 0xEA, 0xA6, 0x27,
361 0xB7, 0xFE, 0x6C, 0x49, 0x47, 0x3B, 0x70, 0x6C, 0xEB, 0xCD, 0xC5, 0x0B, 0x8C, 0x31, 0x29, 0x42,
362 0x4E, 0x10, 0x2B, 0x2D, 0x46, 0xEC, 0x39, 0xA3, 0x90, 0x4B, 0x25, 0x60, 0x9C, 0x62, 0xD4, 0x20,
363 0xF6, 0x16, 0xA8, 0x9C, 0xE4, 0x20, 0xED, 0xC7, 0xBA, 0x5E, 0xB6, 0x4E, 0x03, 0x15, 0xA6, 0xF6,
364 0x23, 0x98, 0x32, 0xC0, 0xAE, 0xA3, 0xFD, 0xD3, 0x7F, 0xF8, 0xED, 0xF0, 0x29, 0x29, 0x12, 0xB3,
365 0xB7, 0x58, 0xAD, 0xA2, 0x58, 0x2C, 0x70, 0x1B, 0xA4, 0x25, 0xE8, 0xA5, 0x43, 0xF1, 0xB9, 0x8F,
366 0x1E, 0x3B, 0x10, 0xDF, 0x52, 0xFE, 0x58, 0x29, 0xAD, 0x3F, 0x99, 0x4D, 0xDF, 0xD2, 0x08, 0x06,
367 0xA1, 0x1C, 0x66, 0x29, 0x26, 0x80, 0x52, 0x8A, 0x5A, 0x73, 0xE7, 0xDF, 0xC1, 0xC4, 0x47, 0x82,
368 0xAB, 0x5C, 0x32, 0xAE, 0x96, 0x04, 0x2B, 0xC3, 0x2D, 0x5A, 0xD2, 0xB0, 0x64, 0x88, 0x97, 0xBF,
369 0x7E, 0x99, 0x60, 0xCC, 0x63, 0x76, 0x66, 0xE9, 0x9A, 0x3D, 0xBB, 0xF7, 0x7F, 0xE4, 0x7C, 0x3F,
370 0xB8, 0x4D, 0x10, 0x8D, 0x2A, 0xEA, 0x3C, 0xD3, 0x03, 0x74, 0xE6, 0x46, 0xC0, 0x29, 0xAE, 0xB0,
371 0x79, 0xBE, 0xCB, 0x18, 0x34, 0xBE, 0x5A, 0xE9, 0x19, 0x8F, 0xA3, 0x8F, 0xD6, 0x6A, 0x6C, 0x88,
372 0x1E, 0x21, 0x08, 0x15, 0xC4, 0xE7, 0xE6, 0xBA, 0x97, 0x9C, 0x4F, 0x89, 0x9F, 0x1A, 0x67, 0x4F,
373 0xC0, 0xD5, 0x72, 0x51, 0x16, 0xB4, 0xD3, 0x8A, 0x1F, 0xE3, 0x92, 0x02, 0x7F, 0x59, 0x56, 0x8F,
374 0x07, 0x8D, 0xC1, 0xC2, 0x42, 0x69, 0x3C, 0xA6, 0xBF, 0x3D, 0xDF, 0x0D, 0xAA, 0x4F, 0x7E, 0x80,
375 0x07, 0x11, 0xE2, 0x94, 0x19, 0x9B, 0x16, 0x26, 0x1A, 0x46, 0x09, 0x0D, 0xB5, 0xB8, 0x8E, 0x01,
376 0x9C, 0xFE, 0x09, 0xB3, 0x60, 0xC2, 0xAE, 0x50, 0x3C, 0x68, 0x75, 0x4A, 0x57, 0xD8, 0x4F, 0xD7,
377 0xA2, 0x76, 0x2C, 0xC1, 0xA2, 0x23, 0xBC, 0x54, 0x2A, 0xDD, 0xF3, 0xDD, 0xA7, 0x34, 0xF7, 0x5C,
378 0xF4, 0x86, 0x23, 0x48, 0x7C, 0x3F, 0x05, 0x40, 0x0E, 0xB0, 0xE5, 0xEB, 0x3E, 0xDF, 0x6A, 0x83,
379 0x65, 0xA0, 0xB2, 0x06, 0xD1, 0x40, 0x79, 0x0D, 0xDE, 0x95, 0x84, 0x96, 0x87, 0x6F, 0xCE, 0x48,
380 0x24, 0x13, 0x0B, 0xF5, 0xC7, 0xF5, 0xA8, 0x7F, 0x2E, 0xC7, 0xE1, 0xBA, 0xAE, 0x2B, 0xF7, 0xF0,
381 0x8E, 0xF7, 0x54, 0x0B, 0xF0, 0xD2, 0x41, 0x81, 0x68, 0x3B, 0x1E, 0x35, 0xAB, 0xD9, 0x2B, 0x46,
382 0x57, 0xE8, 0x53, 0xDF, 0xDE, 0x10, 0xEF, 0xCB, 0x4C, 0xE0, 0x52, 0x18, 0x2C, 0x4E, 0xB9, 0x20,
383 0xE9, 0x7E, 0x85, 0xDF, 0x75, 0x32, 0xE6, 0x10, 0xE9, 0x9C, 0x7B, 0x2E, 0x4C, 0xDA, 0x46, 0xE6,
384 0xCC, 0x77, 0x36, 0x1D, 0x4A, 0x15, 0xF5, 0x32, 0x18, 0x6B, 0x7E, 0xAA, 0xCC, 0x97, 0xCC, 0xD1,
385 0x2F, 0xE5, 0x58, 0x03, 0x35, 0x35, 0x3D, 0xA0, 0x2B, 0x13, 0x3A, 0x65, 0xFF, 0x24, 0x72, 0xCF,
386 0xA7, 0x6D, 0x52, 0x55, 0xF6, 0xC2, 0x30, 0x23, 0x7D, 0x9B, 0x9E, 0xB0, 0x94, 0x02, 0xAD, 0x60,
387 0x8A, 0x9F, 0xBC, 0xC8, 0xE4, 0x2B, 0x92, 0x96, 0xF5, 0xAE, 0x04, 0xA4, 0x33, 0x0C, 0x90, 0x67,
388 0xF0, 0xB9, 0x1E, 0x7E, 0xBE, 0x02, 0x18, 0xB2, 0x03, 0xB6, 0x40, 0xBF, 0x05, 0xE3, 0x76, 0x98,
389 0x21, 0x38, 0xC9, 0x5F, 0xD3, 0x51, 0x8B, 0x43, 0x0B, 0x1A, 0x0B, 0xF9, 0x3C, 0x21, 0x6C, 0x3D,
390 0xB8, 0xA0, 0x57, 0xCA, 0x68, 0xCD, 0x1E, 0xD2, 0x2C, 0x50, 0xEE, 0xC0, 0xDF, 0x25, 0x88, 0x52,
391 0x37, 0xE1, 0x44, 0xC6, 0x76, 0x3B, 0x91, 0x95, 0x86, 0x76, 0x87, 0x49, 0x21, 0x93, 0x44, 0x0A,
392 0x52, 0xB9, 0x2D, 0x2B, 0xE3, 0x1D, 0xB0, 0xE4, 0x98, 0xC6, 0xEE, 0x3D, 0x96, 0x53, 0x4B, 0xFF,
393 0x39, 0x00, 0xD5, 0x42, 0x7E, 0xE1, 0x4C, 0x6F, 0xD5, 0xB7, 0xE6, 0x99, 0x2A, 0x5B, 0x67, 0xEE,
394 0x3E, 0xBA, 0xF7, 0xEC, 0x43, 0x2A, 0x1C, 0xB6, 0xB5, 0x04, 0x26, 0x59, 0xB1, 0x4C, 0x17, 0xCC,
395 0x83, 0xB9, 0x00, 0x3E, 0x36, 0x91, 0x90, 0xF7, 0x5E, 0x38, 0xDC, 0xE4, 0x15, 0xC7, 0x67, 0xF0,
396 0xCA, 0xC8, 0xD2, 0x91, 0x5D, 0x74, 0xAC, 0x97, 0x56, 0x36, 0x1A, 0x82, 0x0A, 0xAA, 0xB4, 0x4E,
397 0xBF, 0x29, 0x5C, 0xBF, 0x58, 0xB3, 0x97, 0xF9, 0xEB, 0x7C, 0x85, 0xB4, 0xA5, 0x13, 0x2F, 0xD1,
398 0xDE, 0x1C, 0xEC, 0x97, 0xDD, 0xE2, 0x39, 0xE4, 0xFB, 0x0A, 0x02, 0xE0, 0xC3, 0xBA, 0x39, 0x79,
399 0xAA, 0x1C, 0x37, 0x75, 0x25, 0x54, 0xBE, 0x85, 0x74, 0x2C, 0xFA, 0x0C, 0xFA, 0x50, 0xF6, 0xBE,
400 0x9F, 0x2A, 0x53, 0x7C, 0x27, 0x46, 0x68, 0x2D, 0x74, 0x2B, 0x46, 0xDA, 0xF5, 0x07, 0x95, 0x09,
401 0x6A, 0x91, 0xB7, 0xB1, 0x34, 0x07, 0x5F, 0xEA, 0xBE, 0x0F, 0x87, 0x28, 0x68, 0x97, 0x43, 0x77,
402 0xD5, 0x38, 0x2B, 0x11, 0x11, 0x4F, 0xD9, 0x75, 0x5E, 0xE1, 0x06, 0xA0, 0x3B, 0xAC, 0x32, 0xFE,
403 0xBF, 0x73, 0x59, 0x5B, 0xA2, 0xA8, 0x7E, 0x10, 0x4C, 0x6E, 0x78, 0xF0, 0x4A, 0x4E, 0x95, 0xD6,
404 0xDD, 0x05, 0x7A, 0xBB, 0xF1, 0xEB, 0xA8, 0xA4, 0x5D, 0x91, 0xF0, 0xED, 0xDB, 0xB8, 0x01, 0x41,
405 0xF8, 0x97, 0x7F, 0xC3, 0x91, 0x53, 0xBF, 0xE9, 0xEA, 0x33, 0x1F, 0xDC, 0xA6, 0xE6, 0x8D, 0xCB,
406 0x75, 0xD0, 0x69, 0xD0, 0xA4, 0x59, 0xA5, 0x02, 0xFC, 0x60, 0x0D, 0x6A, 0xA0, 0x05, 0x1A, 0x54,
407 0x8A, 0xA7, 0x57, 0xA3, 0xF0, 0x90, 0x8A, 0xD5, 0x6F, 0x1E, 0x2E, 0x10, 0x9A, 0x93, 0x2B, 0x51,
408 0x2C, 0xFD, 0x99, 0xE5, 0x9B, 0x5D, 0xB2, 0xA7, 0x37, 0x99, 0x26, 0x35, 0xCA, 0xDD, 0x22, 0x19,
409 0x59, 0x2A, 0xB0, 0x99, 0x23, 0xDF, 0xA7, 0xA9, 0x85, 0x12, 0xCF, 0xBF, 0xFC, 0x74, 0x80, 0x87,
410 0xE1, 0x97, 0xD0, 0xF9, 0xEF, 0x5F, 0x1B, 0x45, 0xF7, 0x76, 0xDB, 0x66, 0x39, 0x05, 0x43, 0x06,
411 0xA9, 0x9F, 0x2E, 0x14, 0x9F, 0x1C, 0x0C, 0x1F, 0xD5, 0xD9, 0xA4, 0x8D, 0x18, 0x6F, 0x08, 0x53,
412 0x0B, 0x92, 0x9A, 0x0C, 0xEA, 0x4C, 0xE4, 0x1D, 0x9E, 0x9A, 0x51, 0xB8, 0x7E, 0x2D, 0xE7, 0x3C,
413 0xFF, 0x84, 0x5C, 0xBF, 0x8F, 0x8C, 0x89, 0x09, 0x1B, 0x7E, 0x4B, 0xE7, 0x85, 0xEC, 0x04, 0xB5,
414 0x20, 0x18, 0x1E, 0x55, 0xD5, 0x5B, 0xAC, 0xC6, 0x25, 0x5A, 0xA1, 0x81, 0xC1, 0x31, 0x9C, 0xF5,
415 0xB5, 0x54, 0x07, 0x65, 0x0A, 0x5B, 0x90, 0x06, 0x4F, 0x84, 0xB2, 0x7F, 0xD1, 0xAD, 0x16, 0x81,
416 0x25, 0xAF, 0xAF, 0xE2, 0x03, 0xA9, 0x1F, 0x13, 0x02, 0x5D, 0x54, 0x89, 0xCD, 0x44, 0x51, 0xEB,
417 0xA4, 0x2B, 0xBD, 0x47, 0xB0, 0xB6, 0x27, 0x1D, 0x9B, 0x14, 0x6F, 0xBF, 0xCD, 0x59, 0xBC, 0x0A,
418 0x37, 0xA8, 0x74, 0x7D, 0x16, 0x90, 0x28, 0xD5, 0x94, 0xC3, 0xE4, 0x23, 0xC4, 0x98, 0x91, 0xCE,
419 0x55, 0xBD, 0x21, 0x3B, 0x84, 0xBD, 0x44, 0x3C, 0xF9, 0xCD, 0x37, 0x43, 0x4A, 0xC6, 0x8C, 0x23,
420 0x04, 0x28, 0x63, 0x7A, 0x03, 0x85, 0xD2, 0x46, 0x93, 0xCA, 0xFE, 0xC3, 0x83, 0x0B, 0x13, 0xCC,
421 0x5D, 0xCB, 0xBA, 0xCA, 0x68, 0xAB, 0x05, 0xF7, 0xEC, 0x4A, 0x9C, 0x0F, 0xD5, 0xC4, 0x5A, 0xA5,
422 0xA0, 0x04, 0x41, 0x6A, 0xF6, 0xEF, 0x16, 0x9B, 0x69, 0x38, 0xF6, 0x2D, 0xAA, 0xEB, 0x2D, 0xE2,
423 0x82, 0xA2, 0x9F, 0x6F, 0xBD, 0x2A, 0xE3, 0x66, 0x6B, 0x21, 0xDA, 0x56, 0xAD, 0x82, 0x2B, 0x93,
424 0xF3, 0x25, 0xEA, 0xFC, 0xFD, 0xFD, 0x1B, 0xA9, 0xFC, 0xB8, 0xC6, 0x98, 0x45, 0xF2, 0x70, 0x03,
425 0x4A, 0x9C, 0x60, 0x82, 0x65, 0xB6, 0x68, 0x4C, 0xE7, 0x41, 0x10, 0x9D, 0x59, 0x40, 0x03, 0x02,
426 0x07, 0x12, 0x33, 0xAF, 0x79, 0xE1, 0xC4, 0xEB, 0xB8, 0xCE, 0x6A, 0x90, 0x72, 0x61, 0x5D, 0x56,
427 0xC7, 0x59, 0x31, 0xCB, 0x45, 0x2D, 0x42, 0x9F, 0x10, 0x1D, 0x09, 0x63, 0x59, 0x8C, 0x6C, 0xDB,
428 0x11, 0xCF, 0xA1, 0xDF, 0x5F, 0x4D, 0xDF, 0xB4, 0xC3, 0x82, 0xEE, 0x58, 0x16, 0xB4, 0x74, 0xFA,
429 0xBE, 0x11, 0x9C, 0x1E, 0x98, 0x29, 0xDE, 0xE3, 0xE5, 0x9E, 0xCF, 0xD7, 0x91, 0x0A, 0xA3, 0xA4,
430 0x42, 0xA1, 0x95, 0x09, 0x9E, 0x16, 0xD5, 0xA8, 0x24, 0x56, 0x5B, 0x23, 0xC8, 0x56, 0x4C, 0xCB,
431 0x89, 0x18, 0x69, 0xEB, 0x0C, 0x1F, 0xC0, 0x41, 0x5C, 0x63, 0x04, 0x68, 0xB2, 0x0F, 0x3F, 0x88,
432 0x36, 0xDD, 0x23, 0x4D, 0x4C, 0xC0, 0x81, 0xE3, 0xE9, 0xAD, 0xE0, 0x27, 0xD5, 0xE5, 0x46, 0xEB,
433 0xFF, 0x32, 0xA2, 0xB7, 0x14, 0x64, 0x0B, 0x6D, 0x1B, 0xE5, 0xD8, 0xAE, 0x9D, 0xE8, 0x55, 0xB9,
434 0x52, 0x70, 0x59, 0xB8, 0x72, 0x92, 0x69, 0x37, 0x95, 0x61, 0x0A, 0xE5, 0xF6, 0x55, 0x97, 0x1D,
435 0xBF, 0xF7, 0x29, 0x77, 0x0F, 0x72, 0x80, 0xB2, 0x7E, 0x56, 0xBF, 0xFD, 0xE9, 0xF5, 0x9B, 0x62,
436 0xE9, 0xBD, 0x0B, 0xC2, 0x07, 0x55, 0x31, 0x4C, 0x57, 0x3A, 0x05, 0xB9, 0x27, 0x41, 0x4A, 0xC3,
437 0xEC, 0x72, 0x20, 0xB3, 0x0C, 0xF9, 0xD9, 0x3A, 0x14, 0x6A, 0x03, 0x44, 0x6A, 0xF1, 0x41, 0x55,
438 0x7F, 0x81, 0xC2, 0x04, 0xA8, 0x05, 0xB9, 0x49, 0x2E, 0x43, 0xC4, 0x00, 0x87, 0x86, 0x04, 0xAC,
439 0xAF, 0x73, 0x78, 0x0E, 0xA4, 0x43, 0x5B, 0x36, 0xA2, 0x8F, 0x9C, 0xF7, 0x66, 0x4A, 0x5A, 0x09,
440 0x6B, 0xAA, 0x69, 0x6F, 0xB1, 0x20, 0x0D, 0x56, 0x85, 0x0A, 0x5E, 0x06, 0xBF, 0xE2, 0x32, 0xB4,
441 0x5C, 0x46, 0x33, 0x0D, 0x27, 0xA3, 0x6B, 0xE1, 0xB2, 0x6A, 0x7D, 0x4A, 0xA7, 0x81, 0x0F, 0x2B,
442 0x16, 0x7C, 0x51, 0xD6, 0xC0, 0x3D, 0xB9, 0xFE, 0xB4, 0x66, 0xC4, 0xB6, 0x54, 0x53, 0x67, 0xDA,
443 0x70, 0x96, 0x9A, 0x0A, 0x07, 0x1A, 0x26, 0xBA, 0x85, 0x50, 0xF5, 0x27, 0x53, 0x9C, 0x3A, 0x94,
444 0x0A, 0x7D, 0xDB, 0xE1, 0xC3, 0xE3, 0x6A, 0x3E, 0x9E, 0xD5, 0x13, 0x0A, 0xA3, 0xD2, 0x21, 0x75,
445 0x79, 0x17, 0x26, 0xAC, 0x48, 0x5F, 0x3D, 0xE1, 0x7D, 0xA4, 0xB1, 0x56, 0x0F, 0x92, 0x2C, 0x60,
446 0xE6, 0xCB, 0x87, 0x35, 0xB8, 0x75, 0xC3, 0xA2, 0x03, 0x50, 0x4B, 0xA2, 0x6E, 0x01, 0xE1, 0xDD,
447 0x87, 0xA5, 0x33, 0xC6, 0x2F, 0xA2, 0x41, 0xFC, 0x72, 0x98, 0xA2, 0x69, 0x4C, 0x3F, 0xF0, 0x53,
448 0xF5, 0x41, 0x2B, 0x23, 0x24, 0x3B, 0xCE, 0x9D, 0x39, 0x31, 0x17, 0x08, 0xE1, 0x3F, 0x5F, 0xFB,
449 0x00, 0xFA, 0xF1, 0xE3, 0xE1, 0x7B, 0x0C, 0xDF, 0x8D, 0xA2, 0xC4, 0xCD, 0x62, 0x3D, 0xAE, 0xC7,
450 0x48, 0x09, 0x1C, 0x66, 0xCB, 0x0E, 0x23, 0xE8, 0x1B, 0x9F, 0x1B, 0xCB, 0xF8, 0x14, 0xC3, 0x34,
451 0x91, 0x32, 0x2B, 0x39, 0x1C, 0xBA, 0x1C, 0xA0, 0x19, 0xF2, 0x57, 0x9D, 0x78, 0x00, 0x55, 0x1F,
452 0x15, 0x12, 0x9A, 0xA2, 0xF2, 0xC2, 0xB7, 0x4E, 0xEA, 0x46, 0x01, 0xC2, 0xE9, 0x76, 0xBF, 0xDE,
453 0xCF, 0x8B, 0xC7, 0x50, 0x80, 0xEE, 0x46, 0x91, 0x93, 0x1E, 0x5C, 0x48, 0x5D, 0xC8, 0xC8, 0x63,
454 0xD1, 0x89, 0x02, 0x29, 0xE9, 0x90, 0x9F, 0x0B, 0x0A, 0x1A, 0x44, 0x17, 0xE7, 0x4E, 0xAD, 0x58,
455 0x55, 0xF8, 0x38, 0xF6, 0x4F, 0xD8, 0x1C, 0x7E, 0x25, 0x9B, 0x59, 0x16, 0xBC, 0x65, 0x24, 0xC5,
456 0xA7, 0x56, 0xE5, 0x20, 0x3F, 0xD9, 0x27, 0xE0, 0x32, 0x24, 0xE1, 0x7B, 0xE1, 0x32, 0xEA, 0xF4,
457 0xFE, 0xD9, 0xA5, 0xFF, 0x35, 0xAE, 0xA9, 0x1B, 0x38, 0x28, 0x6A, 0xC0, 0x1A, 0x42, 0xD9, 0x5E,
458 0x14, 0x2C, 0xC2, 0x2D, 0x9B, 0x94, 0x5B, 0xCF, 0x83, 0x30, 0xB9, 0x06, 0xAF, 0x4B, 0xD7, 0xF6,
459 0x38, 0x7C, 0xFF, 0xB4, 0xA5, 0x1A, 0xA0, 0xE9, 0xF3, 0x01, 0xE3, 0x97, 0xC4, 0xA9, 0x57, 0xF5,
460 0xB9, 0x96, 0xA7, 0xA3, 0xB8, 0x10, 0x0E, 0xFB, 0x1D, 0x39, 0x44, 0x16, 0x97, 0x94, 0x3E, 0x5F,
461 0xAF, 0x0F, 0xE3, 0x99, 0xDC, 0xA0, 0xE9, 0x8D, 0x26, 0x2B, 0xD9, 0xAE, 0xEC, 0x4C, 0x4F, 0x09,
462 0x86, 0x7E, 0x7B, 0xC3, 0xE3, 0xC6, 0x17, 0xAE, 0x30, 0x9C, 0x31, 0xD1, 0x84, 0x47, 0xAF, 0xCB,
463 0xEA, 0x69, 0x2A, 0x08, 0x3E, 0x13, 0x00, 0xDE, 0xF6, 0x4A, 0x42, 0xD3, 0xBE, 0x33, 0xD9, 0x50,
464 0x6B, 0x8D, 0x59, 0x12, 0x1A, 0xD3, 0xA7, 0x7C, 0x0A, 0xE7, 0x87, 0x47, 0xCA, 0xAA, 0x33, 0xFD,
465 0xC1, 0xF6, 0x28, 0xC1, 0x62, 0xA2, 0x4C, 0x79, 0x83, 0x48, 0x86, 0x0E, 0xA4, 0x67, 0x34, 0x95,
466 0xAE, 0x7D, 0xD6, 0xEE, 0x91, 0x05, 0x35, 0x91, 0xE8, 0x34, 0x39, 0xA3, 0xE5, 0xE6, 0x80, 0x53,
467 0x76, 0x1F, 0x94, 0xA0, 0xF6, 0xA5, 0x41, 0x79, 0x82, 0xD3, 0xB0, 0x1F, 0xCE, 0xE1, 0x86, 0x64,
468 0x65, 0x0C, 0x8D, 0xD6, 0xFA, 0xC1, 0x10, 0x6C, 0x07, 0xD5, 0xF0, 0x77, 0x65, 0xB9, 0x0C, 0xBD,
469 0xAE, 0x2D, 0x62, 0x6C, 0x42, 0x7E, 0x2A, 0xBE, 0x5F, 0xC1, 0x17, 0x3B, 0x07, 0xFF, 0x5E, 0xD7,
470 0x31, 0x52, 0x26, 0x2F, 0x9F, 0x12, 0xD8, 0x2E, 0xA3, 0xF5, 0xB5, 0xD2, 0xFC, 0x6E, 0x08, 0x1F,
471 0xC8, 0x93, 0xA1, 0xEB, 0xF9, 0x13, 0x1D, 0x1F, 0x98, 0x5E, 0xB0, 0x0C, 0x65, 0x6C, 0xAE, 0x07,
472 0x78, 0xF8, 0x12, 0xD2, 0xD1, 0x1E, 0x77, 0x5C, 0x24, 0x62, 0xE5, 0x94, 0xD6, 0x6A, 0x8E, 0xD0,
473 0x72, 0x59, 0xDA, 0x48, 0x38, 0x2F, 0x31, 0x75, 0x0C, 0x52, 0xF0, 0x0C, 0x8F, 0x5C, 0xE9, 0x5E,
474 0x5A, 0x94, 0xE8, 0xD2, 0x80, 0xF8, 0x4F, 0xE7, 0xAA, 0x6C, 0xBE, 0x47, 0xFB, 0xDD, 0x57, 0x0A,
475 0xD8, 0x5E, 0xCC, 0x0D, 0x8F, 0x42, 0x5E, 0xDC, 0x5D, 0x95, 0x95, 0x60, 0x9B, 0x6F, 0x05, 0x5E,
476 0x08, 0x45, 0x91, 0xE4, 0xB8, 0x06, 0xB1, 0xF2, 0xC0, 0xD7, 0xE3, 0x47, 0xB7, 0x38, 0x08, 0xA8,
477 0x58, 0xE4, 0x55, 0xFC, 0xE2, 0x37, 0x1F, 0x38, 0xA2, 0x18, 0x9E, 0xC2, 0x0F, 0x90, 0x14, 0x20,
478 0x50, 0xD1, 0xD0, 0xAB, 0x36, 0x7F, 0xAA, 0x03, 0x1C, 0xE6, 0x0A, 0xF9, 0x8E, 0x41, 0xDB, 0x32,
479 0x1C, 0x68, 0xA0, 0xA0, 0xED, 0x4A, 0xF4, 0x4B, 0x09, 0xD0, 0xF0, 0x01, 0x8B, 0x17, 0x44, 0xE1,
480 0xEA, 0xC5, 0x9D, 0x3B, 0x37, 0x7A, 0x68, 0xF1, 0x78, 0x46, 0xCF, 0xB6, 0x57, 0xDB, 0x4B, 0x5C,
481 0x03, 0xE1, 0x9D, 0xC0, 0x37, 0x55, 0x8D, 0x03, 0xFB, 0x6A, 0x00, 0x82, 0x19, 0xD1, 0xC0, 0x76,
482 0x97, 0xEE, 0xC9, 0xAD, 0x0D, 0x72, 0x0B, 0xE9, 0xA8, 0x09, 0x92, 0x03, 0xA4, 0xAA, 0x2C, 0xCF,
483 0xFD, 0xDE, 0x86, 0xD0, 0x06, 0x4A, 0xAE, 0x7E, 0xC1, 0xB8, 0x2A, 0x4E, 0x9F, 0xA3, 0x5E, 0x8C,
484 0x12, 0x40, 0x74, 0x38, 0xE7, 0xEA, 0xB0, 0x51, 0xC2, 0xB9, 0x6D, 0x4A, 0x50, 0xBF, 0x59, 0x9C,
485 0x05, 0xB2, 0x42, 0xE2, 0x0F, 0x71, 0x44, 0xDB, 0x97, 0x0B, 0xD0, 0xDB, 0x44, 0x1F, 0x9A, 0x3B,
486 0x18, 0x2A, 0x7B, 0xD9, 0x03, 0x83, 0x0B, 0xCF, 0x27, 0x20, 0x43, 0xA6, 0x42, 0xED, 0x89, 0x63,
487 0xDB, 0x2D, 0x27, 0xC2, 0x3B, 0xE6, 0x0D, 0x3E, 0xB6, 0x96, 0x33, 0x70, 0xA6, 0xF3, 0xF5, 0x56,
488 0xEA, 0xEB, 0xF1, 0xE7, 0xD8, 0xCB, 0x04, 0x48, 0x99, 0x4C, 0x00, 0xA4, 0x2A, 0xA5, 0x8A, 0xF1,
489 0x58, 0xD5, 0x17, 0x4C, 0xC5, 0x88, 0x06, 0x8F, 0xA6, 0x67, 0xA6, 0x14, 0xC7, 0xB9, 0xE0, 0x86,
490 0xAC, 0x67, 0xFD, 0xB3, 0x5B, 0x3E, 0xDF, 0x03, 0xFD, 0xC8, 0xC4, 0x4A, 0x32, 0x78, 0x6B, 0xD1,
491 0xC1, 0xE2, 0x36, 0x9D, 0x0B, 0xF2, 0x54, 0x25, 0xB8, 0xB7, 0xB2, 0x10, 0x7A, 0xA6, 0x79, 0x52,
492 0xC2, 0xEE, 0x98, 0xA5, 0x3D, 0xF0, 0x07, 0x8D, 0x25, 0xC3, 0xAC, 0xFD, 0xCF, 0x83, 0x98, 0x80,
493 0x56, 0x95, 0xC4, 0x14, 0xA2, 0xA5, 0x93, 0xFE, 0x24, 0x59, 0x44, 0x73, 0xDF, 0xD6, 0x47, 0xDA,
494 0x22, 0x3A, 0x82, 0xC5, 0xD1, 0x59, 0x40, 0x9D, 0x0C, 0x1A, 0xB7, 0x79, 0x45, 0x9A, 0xF8, 0x6D,
495 0x5A, 0x5C, 0xC2, 0x80, 0xFC, 0xAA, 0x8A, 0xA4, 0xFE, 0x68, 0x61, 0x7D, 0xFE, 0x2C, 0x36, 0xE3,
496 0xE0, 0x59, 0x28, 0x40, 0x79, 0xAD, 0x2D, 0x28, 0x12, 0x30, 0xFC, 0x56, 0x2E, 0x1D, 0xEC, 0x48,
497 0x3A, 0xF0, 0xC5, 0x6C, 0x31, 0xE0, 0x2E, 0xB3, 0x91, 0x70, 0xB9, 0x9E, 0xBD, 0xE7, 0x96, 0x58,
498 0xCB, 0xBC, 0x1C, 0xE4, 0xC7, 0x78, 0xC7, 0x1E, 0x39, 0xDB, 0xB8, 0x77, 0x50, 0xB7, 0x65, 0x20,
499 0x04, 0x16, 0x8B, 0xFC, 0x66, 0xC4, 0x6D, 0x05, 0x8C, 0x3C, 0xB6, 0x32, 0x2F, 0xDE, 0xC3, 0x6F,
500 0xFC, 0x82, 0x06, 0x02, 0x87, 0x47, 0xFD, 0xD8, 0xDA, 0x75, 0xE0, 0x4E, 0x8C, 0x40, 0x00, 0xB2,
501 0x9B, 0x35, 0x78, 0xA4, 0x61, 0x64, 0x96, 0x62, 0x37, 0xF6, 0x3E, 0x39, 0xFA, 0x14, 0x5B, 0xC4,
502 0x70, 0x17, 0xDC, 0x0C, 0x9E, 0x31, 0x82, 0x2C, 0x63, 0xCC, 0x8A, 0x43, 0x7C, 0x69, 0x12, 0x05,
503 0x18, 0xA3, 0x62, 0xCC, 0xA2, 0x13, 0x96, 0x25, 0xA6, 0x1B, 0xF2, 0x10, 0xC8, 0x73, 0x4F, 0xCB,
504 0x80, 0xCA, 0xAF, 0x73, 0xC9, 0x78, 0xB1, 0xAE, 0x87, 0xB8, 0xDF, 0x50, 0xD3, 0x55, 0x1E, 0x3A,
505 0x81, 0xF6, 0x84, 0xD6, 0x57, 0x36, 0xCF, 0x38, 0xB7, 0xBC, 0xBC, 0x1E, 0x48, 0x62, 0x9F, 0x0F,
506 0x0C, 0xE5, 0xF0, 0x63, 0x33, 0xE6, 0x59, 0x6B, 0x1E, 0xE6, 0x1C, 0x8A, 0xF9, 0xDD, 0x6B, 0xA3,
507 0xDC, 0x02, 0x4A, 0x2F, 0x8C, 0x6A, 0x8D, 0x16, 0x7E, 0x2F, 0xF1, 0x75, 0xD5, 0x15, 0x93, 0x07,
508 0x27, 0xD9, 0x6F, 0x1A, 0x5D, 0x43, 0xF3, 0x47, 0xC4, 0xED, 0xAD, 0x05, 0x9F, 0xEC, 0x8F, 0xD0,
509 0xBE, 0xB5, 0x58, 0xF4, 0xF6, 0xBE, 0x08, 0x73, 0x96, 0x19, 0x05, 0x25, 0xEC, 0x3D, 0x26, 0xF4,
510 0x93, 0xDB, 0x9F, 0x56, 0x48, 0x4C, 0xBC, 0xD0, 0x02, 0x59, 0xD1, 0x40, 0x4C, 0xA6, 0x06, 0x41,
511 0xE8, 0x7D, 0x47, 0xAE, 0x3A, 0x9E, 0x1A, 0x71, 0x52, 0xD4, 0x67, 0xC1, 0x14, 0x7E, 0x40, 0x6F,
512 0x1C, 0x75, 0x30, 0x7B, 0x70, 0x3A, 0xE0, 0x37, 0xB7, 0x41, 0x7F, 0xCB, 0x4A, 0xBA, 0xA7, 0xCE,
513 0x56, 0x54, 0xC5, 0x46, 0x65, 0x6F, 0xB4, 0xB6, 0xF0, 0x57, 0xCE, 0x2E, 0x4F, 0xA9, 0xF0, 0x14,
514 0x50, 0xC3, 0x30, 0xC5, 0xBA, 0xE1, 0x5E, 0xD6, 0xDC, 0xC5, 0x78, 0x55, 0x32, 0xAA, 0xCB, 0x29,
515 0x35, 0x81, 0x46, 0x5E, 0x92, 0xE7, 0xDE, 0xCC, 0x92, 0x29, 0x86, 0xE0, 0x8F, 0x91, 0x3C, 0x74,
516 0x97, 0x79, 0x63, 0x97, 0x4A, 0xCC, 0x88, 0xB5, 0xA3, 0x7A, 0xF0, 0xF0, 0x33, 0x87, 0xCD, 0xBD
517 };
518 uint8_t b = Value ^ hdSurEncBasicCrypt_D2_0F_11(Value, lookup[(((AddrInd * 2) + 0) * 256) + Value]);
519 return (Value ^ hdSurEncBasicCrypt_D2_0F_11(b, lookup[(((AddrInd * 2) + 1) * 256) + b]));
520}
521
522void hdSurEncPhase1_D2_0F_11(uint8_t *CWs)
523{
524 static const uint8_t lookup1[] =
525 {
526 0x16, 0x71, 0xCA, 0x14, 0xC4, 0xF4, 0xA3, 0x5A, 0x9D, 0x5F, 0x85, 0x8B, 0xA6, 0x77, 0xFD, 0x3C,
527 0x5F, 0x13, 0x2A, 0x5F, 0x61, 0x36, 0xE4, 0xDC, 0x0D, 0x82, 0x92, 0xC5, 0x25, 0xE1, 0x7A, 0x1C,
528 0x29, 0x19, 0x94, 0x2F, 0xC5, 0xD2, 0xDC, 0xBA, 0x86, 0x60, 0x64, 0x60, 0x86, 0x92, 0xA3, 0x4E,
529 0x3D, 0x9B, 0xCC, 0x16, 0xBB, 0xBA, 0xD2, 0xF0, 0x6A, 0xD3, 0x2F, 0x07, 0x75, 0xBD, 0x28, 0xDB
530 };
531 static const int8_t lookup2[] = { 1, -1, -1, 1, -1, 2, 1, -2, -1, 1, 2, -2, 1, -2, -2, 4 };
532 static const int8_t CAddrIndex[] = { 0, 1, 3, 4 };
533 int32_t i, j, i1, i2, i3;
534
535 for(i = 3; i >= 0; --i)
536 {
537 for(j = 0; j <= 15; ++j)
538 {
539 CWs[j] = CWs[j] ^ hdSurEncBasicCrypt_D2_0F_11(j , lookup1 [(16 * i) + j]);
540 }
541
542 uint8_t Buffer[16];
543 uint32_t k;
544 for(i1 = 0; i1 <= 3; ++i1)
545 {
546 for(i2 = 0; i2 <= 3; ++i2)
547 {
548 k = 0;
549 for(i3 = 0; i3 <= 3; ++i3)
550 {
551 k = k + (CWs[(i2 * 4) + i3] * lookup2[(i3 * 4) + i1]);
552 Buffer[(i2 * 4) + i1] = (uint8_t)k;
553 }
554 }
555 }
556 memcpy(CWs, Buffer, 16);
557
558 // CW positions are mixed around here
559 uint8_t a4[4];
560 for(i1 = 1; i1 <= 3; ++i1)
561 {
562 for(i2 = 0; i2 <= 3; ++i2)
563 {
564 a4[i2] = i1 + (i2 * 4);
565 }
566
567 for(i2 = 0; i2 <= i1 - 1; ++i2) // the given code in Func1_3 seems to be wrong here(3 instead of i1-1)!
568 {
569 uint8_t tmp = CWs[a4[0]];
570
571 for(i3 = 1; i3 <= 3; ++i3)
572 {
573 CWs[a4[i3 - 1]] = CWs[a4[i3]];
574 }
575 CWs[a4[3]] = tmp;
576 }
577 }
578
579 for(i1 = 0; i1 <= 15; ++i1)
580 {
581 CWs[i1] = hdSurEncCryptLookup_D2_0F_11(CWs[i1], CAddrIndex[i1 & 3]);
582 }
583 }
584}
585
586void hdSurEncPhase2_D2_0F_11_sub(uint8_t *CWa, uint8_t *CWb, uint8_t AddrInd)
587{
588 uint8_t Buffer[8];
589 uint8_t tmp, i;
590
591 for(i = 0; i <= 7; ++i)
592 {
593 Buffer[i] = hdSurEncCryptLookup_D2_0F_11(CWb[i], AddrInd);
594 }
595
596 // some bitshifting
597 tmp = Buffer[7];
598 for(i = 7; i >= 1; --i)
599 {
600 Buffer[i] = ((Buffer[1] >> 4) & 0xFF) | ((Buffer[i - 1] << 4) & 0xFF);
601 }
602 Buffer[0] = ((Buffer[0] >> 4) & 0xFF) | ((tmp << 4) & 0xFF);
603
604 // saving the result
605 for(i = 0; i <= 7; ++i)
606 {
607 CWa[i] = CWa[i] ^ Buffer[i];
608 }
609}
610
611void hdSurEncPhase2_D2_0F_11(uint8_t *CWs)
612{
613 hdSurEncPhase2_D2_0F_11_sub(CWs, CWs + 8, 0);
614 hdSurEncPhase2_D2_0F_11_sub(CWs + 8, CWs, 1);
615 hdSurEncPhase2_D2_0F_11_sub(CWs, CWs + 8, 2);
616 hdSurEncPhase2_D2_0F_11_sub(CWs + 8, CWs, 3);
617 hdSurEncPhase2_D2_0F_11_sub(CWs, CWs + 8, 4);
618}
619
620void CommonMain_1_D2_13_15(const uint8_t *datain, uint8_t *dataout)
621{
622 const uint8_t Tab3[88] = {
623 0x1B, 0x12, 0x12, 0x0C, 0x12, 0x0C, 0x0C, 0x08, 0x09, 0x09, 0x06, 0x06, 0x06, 0x06, 0x04, 0x04,
624 0x08, 0x04, 0x04, 0x02, 0x04, 0x02, 0x02, 0x01, 0x09, 0x06, 0x09, 0x06, 0x06, 0x04, 0x06, 0x04,
625 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01,
626 0x09, 0x06, 0x06, 0x04, 0x09, 0x06, 0x06, 0x04, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03, 0x02, 0x02,
627 0x04, 0x02, 0x04, 0x02, 0x02, 0x01, 0x02, 0x01, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02,
628 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 };
629
630 int i1,i2;
631 unsigned long bb;
632
633 for (i1 = 0; i1 < 11; i1++)
634 {
635 bb = 0;
636 for (i2 = 0; i2 < 8; i2++)
637 {
638 bb += (Tab3[(i1 * 8) + i2] * datain[i2]);
639 }
640 dataout[i1] = (bb & 0xFF);
641 }
642}
643
644
645unsigned short CommonMain_2_D2_13_15(const uint8_t *data, const unsigned long num)
646{
647 unsigned long bb1, bb2;
648
649 bb1 = num >> 3;
650 bb2 = (data[bb1] << 24) + (data[bb1 + 1] << 16) + (data[bb1 + 2] << 8);
651
652 return ((bb2 >> (21 - (num & 7))) & 0x7FF);
653}
654
655void CommonMain_3_D2_13_15(uint8_t *data0, uint8_t *data1, int nbrloop)
656{
657 int i;
658 unsigned long bb1, bb2;
659
660 bb1 = 0;
661 bb2 = 0;
662 for (i = nbrloop - 1; i >= 0; i--)
663 {
664 bb1 += (data0[i] * 2) + data1[i];
665 bb2 += data0[i] + data1[i];
666 data0[i] = (bb1 & 0xFF);
667 data1[i] = (bb2 & 0xFF);
668 bb1 >>= 8;
669 bb2 >>= 8;
670 }
671}
672
673void CommonMain_D2_13_15(const uint8_t *datain, uint8_t *dataout, int loopval)
674{
675
676 const uint8_t Tab0_Comp[0x800] = {
677 0x54,0x75,0x01,0x0C,0x7C,0xE2,0xC3,0xC2,0x5E,0x13,0x26,0xCA,0xB2,0xCD,0xB8,0x3D,
678 0x02,0x2C,0xE4,0x19,0x41,0x3D,0xE4,0x0F,0xEC,0xF1,0x45,0x83,0xE2,0xE2,0x72,0xF9,
679 0xCD,0x75,0x1E,0x41,0xCC,0x0C,0x1F,0x39,0x87,0x9B,0x46,0xFF,0x68,0x1F,0x00,0xD8,
680 0x41,0x82,0xCA,0xC6,0xEF,0x87,0x90,0xA2,0x7E,0xD9,0xDE,0xC8,0x25,0xEA,0xC9,0x75,
681 0x6E,0x18,0x81,0xD8,0x5A,0xA6,0x74,0x05,0xAF,0xAE,0xE0,0x4F,0x85,0xAD,0x94,0xF6,
682 0x45,0xF4,0xF5,0x55,0xA8,0xEB,0xEC,0xDB,0x6C,0xFF,0x2F,0xC2,0xC3,0x7D,0x93,0xE6,
683 0xF5,0x31,0x96,0xB7,0x9A,0xDB,0xE5,0x76,0x66,0xFB,0xDD,0xBC,0x19,0x18,0x42,0xC6,
684 0x36,0xCD,0x46,0x33,0xEA,0xF1,0x4C,0xC0,0x72,0x07,0xCD,0x61,0xCE,0x0E,0x08,0x01,
685 0xA3,0xFA,0x84,0x21,0xF2,0x43,0x37,0x1C,0xDE,0x25,0x8A,0x1A,0xF4,0xBB,0x40,0xF3,
686 0x53,0xFE,0x17,0x60,0x91,0x6D,0x7B,0x6D,0x5F,0x1C,0x15,0x73,0xCC,0x6E,0x73,0x46,
687 0x27,0x73,0xA3,0x10,0x16,0x32,0xB3,0x39,0x45,0xA6,0x55,0xE7,0x91,0x32,0x24,0xC8,
688 0xAE,0xAF,0x1B,0x28,0x69,0x22,0x2F,0xE9,0x77,0x72,0xBF,0x4B,0x8B,0x07,0x82,0x31,
689 0xB0,0x95,0x10,0x78,0x9F,0xC5,0xF3,0x73,0xE1,0xF8,0x36,0x84,0xFE,0x1B,0x92,0xB2,
690 0xE6,0xA5,0xCE,0xDA,0x56,0x48,0x52,0x77,0x9D,0x9D,0x8E,0x37,0x4B,0xC8,0x35,0x7E,
691 0xB9,0x5D,0xA4,0xAE,0x3F,0xD0,0xAA,0x60,0xA8,0x4C,0x85,0x49,0xF6,0x0C,0x27,0xE8,
692 0x94,0x84,0xA0,0xAA,0x06,0x4D,0xAC,0x58,0x8B,0x61,0x29,0x3D,0x68,0x25,0xD3,0xD3,
693 0x8E,0xA1,0xE0,0x71,0xBF,0x21,0x0C,0xC7,0x18,0x19,0xF1,0x25,0x98,0x5F,0x79,0x5E,
694 0x51,0xBA,0x8C,0x2F,0x52,0x43,0xF3,0x5A,0xE3,0x58,0x97,0x64,0x23,0xE0,0x44,0x4F,
695 0x30,0x2A,0xE0,0x16,0x8D,0x4D,0xD1,0x1F,0x7B,0xC9,0xC5,0x74,0x11,0x23,0x5D,0x95,
696 0xAC,0x7F,0x2E,0x30,0xBE,0x2D,0xE3,0xB5,0xC6,0xA7,0x69,0x99,0x1F,0x18,0x3C,0x96,
697 0x30,0x45,0x99,0x71,0x28,0x08,0x3C,0xF7,0x37,0x4F,0x6A,0xD6,0xAE,0x9B,0x57,0xC1,
698 0xCC,0x2C,0xE2,0x0F,0x7D,0x66,0xF4,0x36,0x0C,0x3B,0x35,0xF6,0x28,0x03,0xA3,0x7A,
699 0x83,0x15,0xF5,0x61,0x5E,0xE8,0xB7,0xD8,0x54,0x33,0x93,0x63,0x80,0x40,0x43,0xD0,
700 0x9C,0xAA,0x3A,0x98,0x50,0xD2,0xB8,0x80,0x5D,0x16,0xDF,0x1C,0x03,0xAA,0x87,0xC7,
701 0x63,0xA5,0x8D,0xA9,0x2E,0xFB,0x4F,0x7C,0x2B,0xF5,0xF9,0x57,0xB5,0x90,0xD8,0x75,
702 0xAB,0x81,0x4C,0x1B,0xAF,0x6C,0x0E,0xCB,0xB1,0x4F,0xD3,0xE3,0x69,0x18,0x8C,0x7A,
703 0x3C,0xE1,0x11,0x86,0x47,0x78,0x11,0xA0,0xD4,0x28,0xC3,0x0D,0xAC,0xC6,0x17,0xA1,
704 0x32,0x9F,0x8F,0x42,0xD9,0x3F,0x66,0xD7,0x2D,0x87,0x7B,0x65,0xD3,0xD6,0x90,0x83,
705 0xA2,0x75,0xE8,0x98,0x90,0x9D,0xDE,0x81,0x9E,0x3D,0xE4,0xA9,0xE4,0x0B,0xBC,0xBA,
706 0x96,0xDD,0x05,0xCA,0xAE,0x78,0x69,0x24,0xDB,0xA7,0x3E,0x7A,0x3B,0xB4,0xC4,0x59,
707 0x61,0xD2,0xF2,0xE3,0x99,0x8F,0x8F,0x8A,0x82,0x33,0xB8,0x17,0x5E,0x7A,0x32,0x41,
708 0x10,0x8D,0xC2,0xEF,0xAA,0xF8,0x5A,0xF7,0xD2,0x1D,0xC0,0xCB,0x5E,0xB7,0x8A,0x78,
709 0x49,0x42,0xEB,0x19,0x1B,0x61,0xA0,0x77,0x5A,0xF4,0x6D,0x55,0xDA,0xEB,0xCE,0x4E,
710 0xB8,0xE6,0x32,0xD7,0x51,0x3F,0x73,0x14,0x34,0x6E,0x38,0xD6,0xA7,0x28,0x87,0x4A,
711 0x59,0xCA,0x1C,0x80,0xB5,0x8C,0x9D,0x94,0xCB,0xFE,0x29,0x41,0xE5,0x69,0xCF,0xFD,
712 0x0B,0xE1,0x7C,0xA1,0x70,0x12,0x76,0x43,0xDA,0xB9,0xD4,0xC3,0x31,0xBC,0x94,0x77,
713 0x04,0xB4,0x1C,0xAA,0xEC,0x6F,0xA5,0x12,0x9D,0x6F,0x34,0x65,0x77,0xA0,0xD2,0x6F,
714 0x60,0xC6,0x47,0xC2,0xDF,0x6A,0x10,0x53,0xD4,0xBA,0xF3,0xB7,0x38,0x79,0x63,0xC9,
715 0xD4,0x77,0xBC,0x54,0xE9,0x79,0x42,0xD5,0xE0,0x71,0xE7,0x9E,0x5A,0x62,0x0C,0xAD,
716 0x01,0x09,0xA8,0x9F,0x8E,0x67,0x4A,0x30,0xA4,0xB1,0x08,0xFC,0x0A,0xEA,0x7A,0x1D,
717 0x4C,0x4A,0x21,0xDE,0x00,0xD7,0x41,0x98,0x6B,0x38,0x50,0x3E,0x1F,0x25,0x06,0xE3,
718 0x6C,0xA3,0x84,0x5B,0xC1,0xED,0x47,0xDD,0xB3,0x83,0x46,0x72,0x69,0xCE,0x72,0x04,
719 0x43,0x67,0x3A,0x19,0xD9,0x0A,0xF7,0x43,0x88,0xCA,0xC7,0x31,0x34,0x21,0x4E,0x4C,
720 0xE8,0xD1,0x70,0x00,0xBD,0xB1,0xB6,0x76,0x6F,0x5B,0xF9,0xF5,0xF4,0x19,0x20,0x21,
721 0xC1,0xF0,0x11,0x36,0x66,0xAB,0x15,0xBD,0x69,0x92,0xC6,0x46,0xDE,0xDC,0xE9,0x9A,
722 0xF8,0x6C,0x15,0x29,0x15,0xA6,0x35,0x3E,0x08,0xE5,0x90,0x62,0x9F,0x86,0x56,0x83,
723 0x5D,0x60,0x0D,0x22,0x77,0xA7,0x60,0x9B,0x26,0x80,0x16,0x67,0xB4,0x46,0xBF,0x74,
724 0x55,0x92,0x5B,0x34,0xFF,0xC8,0x28,0x37,0xFF,0x14,0x62,0xFA,0xBD,0x03,0x78,0x04,
725 0x1B,0x65,0x7F,0x99,0x05,0x27,0x14,0xC0,0x06,0x4D,0x4B,0x0E,0x98,0x34,0x6A,0xB3,
726 0xA1,0xFE,0xBC,0x45,0x7D,0x52,0x50,0x0E,0x2C,0xFB,0x91,0xF5,0xFB,0x2A,0xB7,0xD9,
727 0xB8,0xB8,0x54,0x31,0x81,0x03,0x93,0x2C,0xE1,0x5C,0xB9,0x2C,0xE8,0x38,0xC0,0xA7,
728 0x58,0x18,0x92,0xC5,0x8B,0xEF,0x1E,0x33,0xA4,0xBA,0x86,0x2B,0xE9,0xEE,0xB1,0xDF,
729 0xAB,0xB8,0x48,0xDA,0x84,0xF1,0x68,0x05,0x4E,0xDE,0xB5,0x9E,0x88,0x12,0xC9,0x60,
730 0x50,0x58,0x56,0x9D,0x26,0x84,0xB6,0x1A,0xE6,0x4B,0x40,0x94,0x6D,0xE9,0x1D,0x0D,
731 0x8A,0xF9,0x2A,0xB5,0xBC,0xDB,0x06,0x8F,0x13,0x7E,0x1D,0x1C,0xC7,0xFD,0x8F,0x78,
732 0x55,0x3F,0x16,0x84,0x48,0xDA,0x1A,0xD1,0x93,0x95,0x20,0x58,0x92,0x39,0xF6,0x73,
733 0x4E,0x9E,0x7B,0x70,0xFC,0x1E,0x5B,0x20,0x48,0x96,0xB3,0x7C,0x50,0x09,0x5B,0x61,
734 0x57,0x97,0x36,0x04,0x29,0x2C,0x32,0x8E,0x93,0x4A,0x45,0xFA,0xD5,0x24,0x14,0x1A,
735 0x28,0x9C,0x1A,0x71,0xAE,0x85,0x4B,0x26,0x79,0x99,0x65,0xD0,0x07,0x98,0xED,0xC9,
736 0x1B,0x39,0x57,0x5B,0xDB,0x3D,0x87,0x69,0x66,0x9B,0x03,0x23,0x54,0x6B,0x4B,0xAC,
737 0x6E,0x7A,0x25,0x1E,0xB6,0x97,0xCF,0x1D,0x07,0xCB,0x2A,0x3E,0x85,0x02,0x93,0x31,
738 0x12,0x27,0xF0,0xA6,0x6D,0x0F,0x9A,0xB6,0xFC,0x22,0x79,0x6C,0x77,0xFD,0x3F,0xDC,
739 0x19,0xD0,0xDF,0xBD,0x9E,0xE0,0xBE,0x20,0x13,0xA3,0x0A,0x0B,0x22,0xF2,0xC8,0x6B,
740 0xA1,0xDD,0x6C,0x67,0xB3,0xFD,0x71,0xC2,0x7B,0x08,0x3B,0xF1,0x37,0xB5,0x0F,0x86,
741 0xFA,0xA9,0xE9,0x42,0xD1,0xE8,0xCD,0x05,0xEF,0xD3,0xCC,0x0B,0x70,0x51,0x5B,0x97,
742 0x06,0xC4,0x9D,0x88,0x11,0x3E,0x99,0x9F,0xBE,0x76,0x8C,0x8D,0xE6,0xBA,0xDA,0x48,
743 0xD0,0x04,0x86,0x4F,0xA9,0xC6,0xB0,0xED,0xA4,0x94,0x46,0x96,0x27,0xEE,0x9F,0xBD,
744 0xDA,0x9B,0x3D,0x11,0x80,0xD3,0x7B,0x5A,0x48,0x94,0xE5,0xCC,0x48,0xEA,0xE4,0x18,
745 0xDF,0x51,0xB3,0x02,0x57,0x20,0x4B,0x0F,0x07,0xFF,0x41,0x33,0x0F,0x6B,0x2E,0xAA,
746 0xDE,0xB2,0x56,0xF7,0xFB,0xA2,0x48,0x3C,0x97,0x1A,0x64,0x2C,0xD1,0x74,0x40,0xCF,
747 0x65,0x7F,0x14,0x08,0x59,0xC4,0x35,0xD3,0x8A,0x0F,0xFD,0x71,0x7A,0x71,0xAC,0x2D,
748 0xF3,0xFD,0x7B,0x12,0x5F,0xC0,0xBC,0x4E,0x96,0x12,0xF2,0x8E,0x41,0x84,0x01,0x0F,
749 0xED,0x7B,0xC1,0xB9,0x39,0x03,0x35,0x40,0x49,0x53,0xB8,0xB4,0x6B,0xA6,0xE7,0x0A,
750 0x14,0xBB,0x29,0x16,0xEC,0x2A,0x3A,0xD6,0x09,0xBB,0x5C,0x20,0xF8,0x09,0xFD,0x86,
751 0xC4,0x25,0x09,0x85,0x0B,0xD5,0xD8,0x51,0xB1,0xA2,0xCB,0xDC,0xC4,0xDD,0x34,0xDF,
752 0xE2,0x85,0xA9,0xCC,0x4E,0x66,0x51,0xFA,0x9C,0x4D,0xB7,0x1E,0x3E,0x49,0x34,0x9C,
753 0x21,0x66,0x07,0x44,0xB2,0xEC,0x73,0xC5,0xBB,0x27,0x9A,0xA5,0x91,0x5A,0xB9,0x9F,
754 0xBE,0xC8,0xA2,0x27,0x89,0x21,0xA7,0xEE,0x50,0x4D,0x43,0x50,0x67,0xC2,0x3B,0x7C,
755 0x20,0x0B,0x95,0x40,0xBE,0xEA,0xB5,0xD9,0x82,0xD7,0x9C,0xB5,0x21,0xAD,0xA6,0xF9,
756 0x70,0xEA,0xCD,0x04,0xDD,0x58,0x91,0x89,0xB2,0xA9,0xF9,0xB4,0x12,0xA2,0x63,0x89,
757 0x40,0x8E,0xEA,0x62,0xEE,0x0B,0x01,0x82,0x6F,0xB3,0x5E,0x5C,0x36,0xBE,0xF4,0x97,
758 0x2C,0xCF,0x96,0x7C,0x0D,0xAD,0x62,0xCE,0xD4,0x38,0xC5,0x32,0x02,0x24,0x57,0x27,
759 0xE0,0xCF,0x56,0xA5,0x72,0x6D,0x90,0x89,0x2D,0x4C,0x34,0xF6,0x1D,0xDD,0x88,0x5E,
760 0x7A,0x23,0xE3,0x6F,0x42,0xA3,0xD9,0x58,0x7E,0xE3,0x52,0x74,0x57,0x63,0xB7,0xB2,
761 0xC1,0xA3,0x30,0x92,0x2E,0xB0,0x91,0x01,0x13,0x36,0x9A,0x6A,0xA7,0x5B,0x3C,0x07,
762 0xFB,0xD8,0x1E,0x7E,0xCF,0x49,0xAB,0x3F,0xCA,0xCE,0x74,0x40,0x54,0x8D,0x83,0x61,
763 0xCA,0xC3,0x76,0x59,0x5C,0x9F,0x49,0x8A,0x7D,0xD1,0x17,0x9C,0xA4,0xDB,0xB9,0x16,
764 0x4D,0x64,0xF7,0xC7,0xF0,0x24,0xE7,0x00,0xB6,0x98,0xD5,0x8B,0x54,0xCB,0x1E,0x8B,
765 0xA2,0x2B,0x7D,0x50,0x51,0x8A,0xF0,0xEF,0x47,0xAE,0xD0,0xD6,0xA0,0x42,0x8A,0xD8,
766 0x22,0xAF,0x02,0x99,0x4A,0xE0,0x8D,0x8D,0xBF,0x11,0x05,0xA4,0xC4,0x9D,0xB3,0x89,
767 0xB4,0x4C,0xC9,0xF7,0x4D,0xC5,0x2A,0x35,0x95,0x30,0xF3,0x0E,0x2F,0xEC,0x6E,0x3A,
768 0x8B,0x05,0x76,0xED,0x1A,0x7C,0xC0,0xE7,0x22,0xCB,0x59,0xFF,0xE6,0x37,0x78,0x44,
769 0xD4,0xEE,0xAD,0xD7,0xBD,0x2E,0xB7,0x6A,0xA4,0x4E,0x0E,0xFB,0xB0,0xF5,0xCB,0x87,
770 0xCF,0xC3,0x18,0x64,0x6F,0x26,0x5C,0xD7,0x16,0xC8,0x7F,0xAB,0x29,0xC4,0xBA,0xFF,
771 0xCD,0x1C,0xE4,0x3A,0xF2,0xEB,0x6A,0x38,0xE4,0x65,0xC2,0x33,0x03,0x26,0x7D,0x9B,
772 0x7E,0x1D,0x83,0x00,0x04,0x2D,0x2B,0x5F,0xFE,0x39,0x7E,0xF1,0x3C,0xA2,0x8C,0x52,
773 0x95,0xBF,0x46,0x81,0x24,0x44,0xF8,0x10,0xC3,0x87,0x8E,0x64,0x80,0x17,0x44,0xE2,
774 0x8B,0xD1,0x3C,0x4A,0xE2,0x1F,0xA9,0xDE,0x75,0x13,0xFC,0x2E,0x86,0x0A,0x5C,0x5F,
775 0x92,0x2B,0x92,0x2D,0x2A,0xEC,0xD2,0x5C,0x82,0x6B,0x76,0x1E,0xED,0xE6,0x56,0xF7,
776 0xD2,0xDB,0x96,0x68,0x02,0x68,0x99,0x49,0xEE,0x88,0x66,0xCE,0x5D,0x08,0x88,0xA8,
777 0xB9,0x24,0xB0,0xB4,0xDC,0xA6,0xC9,0xD8,0x68,0x80,0xBF,0x6B,0x32,0x57,0x7F,0x91,
778 0x0E,0x37,0x59,0xF6,0x76,0xD2,0xC5,0x0B,0xF3,0x23,0xBF,0x38,0x52,0x0D,0x97,0x81,
779 0x17,0xBB,0x9A,0xC2,0x55,0x44,0x72,0xCE,0xEE,0xFA,0xBB,0xDA,0xAB,0xB0,0x09,0xEA,
780 0xDB,0xBF,0x45,0x95,0x07,0x88,0xD4,0xD2,0x0D,0x2E,0x15,0x31,0xBE,0x6A,0xF4,0xEF,
781 0xA3,0x7D,0x22,0x81,0x3B,0xA8,0x83,0xF9,0x42,0xE5,0x9B,0x79,0x01,0xF5,0xDC,0x19,
782 0x64,0xEB,0x47,0x67,0xAF,0xA4,0xB2,0xAE,0xF8,0xF9,0x4D,0x63,0xAD,0x54,0xE1,0x02,
783 0x56,0x89,0x4E,0x0A,0xE8,0x3E,0x03,0xFA,0x33,0x61,0x58,0x80,0x64,0x55,0x3C,0x8C,
784 0x2A,0x3D,0x70,0x3E,0xE5,0xC1,0xA7,0x75,0xFC,0x91,0x75,0x05,0x8C,0x6E,0x3A,0x74,
785 0x10,0xF1,0x30,0xE6,0xF6,0xF7,0xAB,0x6C,0xB1,0x2B,0xF0,0x2F,0x13,0x6E,0xD4,0x0A,
786 0x64,0x29,0xF8,0xBB,0xA1,0xAA,0x55,0x09,0x93,0x47,0x2F,0x8C,0x7D,0xF1,0x2D,0x81,
787 0xFE,0x78,0xFC,0xEE,0x3F,0xDD,0x49,0xDC,0x0D,0x52,0x5C,0x3B,0x8F,0x08,0xB0,0xDF,
788 0xDC,0xFC,0xBE,0x5F,0x3B,0x53,0x82,0xE2,0xBD,0x6D,0x5D,0xF2,0x8D,0xFB,0x5A,0x1D,
789 0x15,0x1B,0xE4,0xB1,0x56,0x06,0x1A,0xF8,0x9C,0xB9,0x44,0xF2,0xD9,0xF4,0xB2,0x00,
790 0x9A,0x94,0x62,0x33,0x7E,0x0A,0xB0,0x0C,0xD5,0xEF,0x8E,0xA8,0xEB,0x47,0xE9,0x20,
791 0xA8,0x68,0xEF,0x53,0xA0,0x59,0x1B,0xA0,0x2B,0xC5,0x2B,0x30,0xB6,0x5D,0xAB,0xB4,
792 0x5F,0x86,0x71,0x95,0x89,0xFC,0xC7,0x9A,0xC3,0xED,0x82,0xA0,0x3D,0x73,0xC1,0x36,
793 0x01,0x5F,0x9E,0xD7,0xE3,0xC0,0x62,0x74,0xED,0x13,0xB6,0xD6,0xD5,0x37,0x17,0xE1,
794 0x39,0xC7,0x6D,0x31,0xBA,0x02,0xAF,0xD5,0xCC,0x51,0xA8,0x09,0x3F,0x00,0x4A,0x8F,
795 0xA6,0x23,0x13,0x88,0xCD,0x1F,0x38,0x60,0xE7,0xE7,0x53,0xDC,0x65,0xE8,0x53,0x26,
796 0xBB,0xE1,0x1F,0x65,0xF0,0xAD,0x53,0x3B,0xBD,0xAD,0x97,0xAC,0xD1,0xA5,0xD0,0xE9,
797 0xEB,0xD6,0x11,0xD5,0x00,0xDF,0x72,0x9C,0xCC,0x7F,0xD3,0x67,0xA1,0x3A,0x79,0xE1,
798 0x85,0x70,0xE5,0x43,0xC9,0x28,0xA5,0x2F,0x9E,0xE7,0xFE,0xEB,0x14,0x10,0x23,0xC7,
799 0xAF,0xB1,0x24,0xC8,0xE5,0x44,0x6F,0x4C,0x04,0xEC,0xC1,0xF0,0x23,0x1C,0xF6,0xAC,
800 0xAF,0xC4,0x0E,0x2D,0x59,0x39,0x47,0xA9,0x9E,0xD9,0x2E,0x79,0xBA,0xFE,0x4F,0x12,
801 0x7F,0x63,0x7F,0x62,0x67,0x7C,0x52,0x2F,0xCA,0x8B,0x6B,0x4F,0x10,0x8F,0x14,0xC6,
802 0xA1,0x9B,0x45,0x15,0x90,0x63,0x22,0x5D,0x68,0x4B,0xCF,0xFA,0x6A,0x06,0xF0,0x26,
803 0xAC,0x6C,0x3A,0x89,0x25,0xF3,0x5E,0x90,0x06,0x93,0xB6,0x35,0x0D,0x85,0x60,0x98,
804 0xBC,0x6E,0xF2,0xA5,0x17,0x29,0x70,0xD6,0xFF,0x0C,0xD0,0xC0,0x35,0xD7,0x4A,0xFD };
805
806
807 const uint8_t Tab1_Comp[11*8] = {
808 0x70,0x49,0xD7,0xE3,0xDF,0x3C,0x96,0x03,0x2A,0x70,0x82,0xA6,0x5F,0xDE,0xCC,0x0C,
809 0x2A,0x62,0x2A,0x3E,0xA4,0x0C,0x0A,0xAB,0x4F,0x06,0x5D,0xD4,0x14,0xAA,0xE1,0xC3,
810 0x96,0xDA,0x16,0x36,0x45,0x3C,0x63,0xC2,0x97,0x71,0x87,0xAB,0xFA,0xB2,0xFC,0xD6,
811 0x8F,0x85,0xC9,0x04,0x56,0xBA,0xEB,0x3F,0x42,0x9F,0xCB,0x66,0x55,0x45,0x1C,0x96,
812 0xFF,0x4D,0x35,0xDF,0x88,0x0E,0xDC,0xC8,0x4E,0x3F,0x81,0x74,0xD8,0x77,0x4C,0x8E,
813 0x00,0xC0,0x64,0x83,0x4E,0xBB,0xF0,0xB1 };
814
815 unsigned short buff8[8];
816 uint8_t buff11[11 + 1]; // +1 to avoid func2 bug
817 int i1, i2;
818 buff11[11] = 0;
819
820 CommonMain_1_D2_13_15(datain, buff11);
821 for (i1 = 0; i1 < 11; i1++)
822 {
823 buff11[i1] ^= Tab1_Comp[(loopval * 11) + i1];
824 }
825
826 for (i1 = 0; i1 < 8; i1++)
827 {
828 buff8[i1] = CommonMain_2_D2_13_15(buff11, i1 * 11);
829 }
830
831 for (i1 = 0; i1 < 8; i1++)
832 {
833 dataout[i1] = Tab0_Comp[buff8[i1]];
834 }
835
836 i1 = 1;
837 while (i1 < 8)
838 {
839 i2 = 0 ;
840 while (i2 < 8)
841 {
842 CommonMain_3_D2_13_15(&dataout[i2], &dataout[i1 + i2], i1);
843 i2 += (i1 * 2);
844 }
845 i1 *= 2;
846 }
847}
848
849void Common_D2_13_15(uint8_t *cw0, const uint8_t *cw1, int loopval)
850{
851 int i;
852 uint8_t buff8[8];
853
854 CommonMain_D2_13_15(cw1, buff8, loopval);
855 for (i = 0; i < 8; i++)
856 {
857 cw0[i] ^= buff8[i];
858 }
859}
860
861void ExchangeCWs(uint8_t *cw0, uint8_t *cw1)
862{
863 int i;
864 uint8_t b;
865
866 for (i = 0; i < 8; i++)
867 {
868 b = cw1[i];
869 cw1[i] = cw0[i];
870 cw0[i] = b;
871 }
872}
873
874
875void hdSurEncPhase1_D2_13_15(uint8_t *cws)
876{
877 int i;
878
879 for (i = 0; i <= 7; i++)
880 {
881 // Possible code
882 if ((i & 1) == 0)
883 {
884 Common_D2_13_15((uint8_t *) &cws[0], (uint8_t *) &cws[8], i);
885 }
886 else
887 {
888 Common_D2_13_15((uint8_t *) &cws[8], (uint8_t *) &cws[0], i);
889 }
890 }
891 ExchangeCWs((uint8_t *) &cws[0], (uint8_t *) &cws[8]);
892}
893
894void hdSurEncPhase2_D2_13_15(uint8_t *cws)
895{
896 int i;
897
898 for (i = 7; i >= 0; i--)
899 {
900 // Possible code
901 if ((i & 1) == 0)
902 {
903 Common_D2_13_15((uint8_t *) &cws[8], (uint8_t *) &cws[0], i);
904 }
905 else
906 {
907 Common_D2_13_15((uint8_t *) &cws[0], (uint8_t *) &cws[8], i);
908 }
909 }
910 ExchangeCWs((uint8_t *) &cws[8], (uint8_t *) &cws[0]);
911}
912
913
914static int32_t viaccess_card_init(struct s_reader *reader, ATR *newatr)
915{
916 get_atr;
917 def_resp;
918 int32_t i;
919 uint8_t buf[256];
920 uint8_t insac[] = { 0xca, 0xac, 0x00, 0x00, 0x00 }; // select data
921 uint8_t insb8[] = { 0xca, 0xb8, 0x00, 0x00, 0x00 }; // read selected data
922 uint8_t insa4[] = { 0xca, 0xa4, 0x00, 0x00, 0x00 }; // select issuer
923 uint8_t insc0[] = { 0xca, 0xc0, 0x00, 0x00, 0x00 }; // read data item
924 static const uint8_t insFAC[] = { 0x87, 0x02, 0x00, 0x00, 0x03 }; // init FAC
925 static const uint8_t FacDat[] = { 0x00, 0x00, 0x28 };
926 static uint8_t ins8702_data[] = { 0x00, 0x00, 0x11};
927 static uint8_t ins8704[] = { 0x87, 0x04, 0x00, 0x00, 0x07 };
928 static uint8_t ins8706[] = { 0x87, 0x06, 0x00, 0x00, 0x04 };
929
930 if((atr[1] != 0x77) || ((atr[2] != 0x18) && (atr[2] != 0x11) && (atr[2] != 0x19)) || ((atr[9] != 0x68) && (atr[9] != 0x6C) && (atr[9] != 0x64)))
931 {
932 return ERROR;
933 }
934
935 write_cmd(insFAC, FacDat);
936 if(!(cta_res[cta_lr - 2] == 0x90 && cta_res[cta_lr - 1] == 0))
937 {
938 return ERROR;
939 }
940
941 if(!cs_malloc(&reader->csystem_data, sizeof(struct viaccess_data)))
942 {
943 return ERROR;
944 }
945
946 struct viaccess_data *csystem_data = reader->csystem_data;
947
948 write_cmd(insFAC, ins8702_data);
949 if((cta_res[cta_lr - 2] == 0x90) && (cta_res[cta_lr - 1] == 0x00))
950 {
951 write_cmd(ins8704, NULL);
952 if((cta_res[cta_lr - 2] == 0x90) && (cta_res[cta_lr - 1] == 0x00))
953 {
954 write_cmd(ins8706, NULL);
955 if((cta_res[cta_lr - 2] == 0x90) && (cta_res[cta_lr - 1] == 0x00))
956 {
957 csystem_data->last_geo.number_ecm = (cta_res[2] << 8) | (cta_res[3]);
958 rdr_log(reader, "using ecm #%x for long viaccess ecm", csystem_data->last_geo.number_ecm);
959 }
960 }
961 }
962
963 reader->caid = 0x500;
964 memset(reader->prid, 0xff, sizeof(reader->prid));
965 insac[2] = 0xa4;
966 write_cmd(insac, NULL); // request unique id
967 insb8[4] = 0x07;
968 write_cmd(insb8, NULL); // read unique id
969 memcpy(reader->hexserial, cta_res + 2, 5);
970 // rdr_log(reader, "[viaccess-reader] type: Viaccess, ver: %s serial: %llu", ver, b2ll(5, cta_res+2));
971 rdr_log_sensitive(reader, "type: Viaccess (%sstandard atr), caid: %04X, serial: {%llu}",
972 atr[9] == 0x68 ? "" : "non-", reader->caid, (unsigned long long) b2ll(5, cta_res + 2));
973
974 i = 0;
975 insa4[2] = 0x00;
976 write_cmd(insa4, NULL); // select issuer 0
977 buf[0] = 0;
978 while((cta_res[cta_lr - 2] == 0x90) && (cta_res[cta_lr - 1] == 0))
979 {
980 insc0[4] = 0x1a;
981 write_cmd(insc0, NULL); // show provider properties
982 cta_res[2] &= 0xF0;
983 reader->prid[i][0] = 0;
984 memcpy(&reader->prid[i][1], cta_res, 3);
985 memcpy(&csystem_data->availkeys[i][0], cta_res + 10, 16);
986 snprintf((char *)buf + cs_strlen((char *)buf), sizeof(buf) - cs_strlen((char *)buf), ",%06X", b2i(3, &reader->prid[i][1]));
987 // rdr_log(reader, "[viaccess-reader] buf: %s", buf);
988
989 insac[2] = 0xa5;
990 write_cmd(insac, NULL); // request sa
991 insb8[4] = 0x06;
992 write_cmd(insb8, NULL); // read sa
993 memcpy(&reader->sa[i][0], cta_res + 2, 4);
994
995 insa4[2] = 0x02;
996 write_cmd(insa4, NULL); // select next issuer
997 i++;
998 }
999 reader->nprov = i;
1000 rdr_log(reader, "providers: %d (%s)", reader->nprov, buf + 1);
1001
1002 get_maturity(reader);
1003 if(cfg.ulparent)
1004 {
1005 unlock_parental(reader);
1006 }
1007
1008 rdr_log(reader, "ready for requests");
1009 return OK;
1010}
1011
1012bool dcw_crc(uint8_t *dw)
1013{
1014 int8_t i;
1015 for(i = 0; i < 16; i += 4) if(dw[i + 3] != ((dw[i] + dw[i + 1] + dw[i + 2]) & 0xFF)) { return 0; }
1016 return 1;
1017}
1018
1019static int32_t viaccess_do_ecm(struct s_reader *reader, const ECM_REQUEST *er, struct s_ecm_answer *ea)
1020{
1021 def_resp;
1022 static const uint8_t insa4[] = { 0xca, 0xa4, 0x04, 0x00, 0x03 }; // set provider id
1023 uint8_t ins88[] = { 0xca, 0x88, 0x00, 0x00, 0x00 }; // set ecm
1024 uint8_t insf8[] = { 0xca, 0xf8, 0x00, 0x00, 0x00 }; // set geographic info
1025 static const uint8_t insc0[] = { 0xca, 0xc0, 0x00, 0x00, 0x12 }; // read dcw
1026 struct viaccess_data *csystem_data = reader->csystem_data;
1027
1028 // //XXX what is the 4th uint8_t for ??
1029 int32_t ecm88Len = MIN(MAX_ECM_SIZE - 4, SCT_LEN(er->ecm) - 4);
1030 if(ecm88Len < 1)
1031 {
1032 rdr_log(reader, "ECM: Size of ECM couldn't be correctly calculated.");
1033 return ERROR;
1034 }
1035 uint8_t ecmData[ecm88Len];
1036 memset(ecmData, 0, ecm88Len);
1037 memcpy(ecmData, er->ecm + 4, ecm88Len);
1038 uint8_t *ecm88Data = &ecmData[0];
1039 uint32_t provid = 0;
1040 int32_t rc = 0;
1041 int32_t hasD2 = 0;
1042 uint8_t hasE0 = 0;
1043 int32_t curEcm88len = 0;
1044 int32_t nanoLen = 0;
1045 uint8_t *nextEcm;
1046 uint8_t DE04[MAX_ECM_SIZE];
1047 int32_t D2KeyID = 0;
1048 int32_t curnumber_ecm = 0;
1049 // nanoD2 d2 02 0d 02 -> D2 nano, len 2
1050 // 0b, 0f, 13 -> pre AES decrypt CW
1051 // 0d, 11, 15 -> post AES decrypt CW
1052
1053 int32_t nanoD2 = 0; // knowns D2 nanos: 0x0b ,0x0d ,0x0f ,0x11, 0x13, 0x15
1054
1055 memset(DE04, 0, sizeof(DE04)); //fix dorcel de04 bug
1056
1057 nextEcm = ecm88Data;
1058
1059 while(ecm88Len > 0 && !rc)
1060 {
1061
1062 if(ecm88Data[0] == 0x00 && ecm88Data[1] == 0x00)
1063 {
1064 // nano 0x00 and len 0x00 aren't valid... something is obviously wrong with this ecm.
1065 rdr_log(reader, "ECM: Invalid ECM structure. Rejecting");
1066 return ERROR;
1067 }
1068
1069 // 80 33 nano 80 (ecm) + len (33)
1070 if(ecm88Data[0] == 0x80) // nano 80, give ecm len
1071 {
1072 curEcm88len = ecm88Data[1];
1073 nextEcm = ecm88Data + curEcm88len + 2;
1074 ecm88Data += 2;
1075 ecm88Len -= 2;
1076 }
1077
1078 if(!curEcm88len) // there was no nano 80 -> simple ecm
1079 {
1080 curEcm88len = ecm88Len;
1081 }
1082
1083 // d2 02 0d 02 -> D2 nano, len 2, select the AES key to be used
1084 if(ecm88Data[0] == 0xd2)
1085 {
1086 // test if it needs AES decrypt
1087 if(ecm88Data[2] == 0x0b)
1088 {
1089 nanoD2 = 0x0b;
1090 rdr_log_dbg(reader, D_READER, "ECM: nano D2 0x0b");
1091 }
1092
1093 if(ecm88Data[2] == 0x0d)
1094 {
1095 nanoD2 = 0x0d;
1096 rdr_log_dbg(reader, D_READER, "ECM: nano D2 0x0d");
1097 }
1098
1099 if(ecm88Data[2] == 0x0f)
1100 {
1101 nanoD2 = 0x0f;
1102 rdr_log_dbg(reader, D_READER, "ECM: nano D2 0x0f");
1103 }
1104
1105 if(ecm88Data[2] == 0x11)
1106 {
1107 nanoD2 = 0x11;
1108 rdr_log_dbg(reader, D_READER, "ECM: nano D2 0x11");
1109 }
1110
1111 if(ecm88Data[2] == 0x13)
1112 {
1113 nanoD2 = 0x13;
1114 rdr_log_dbg(reader, D_READER, "ECM: nano D2 0x13");
1115 }
1116
1117 if(ecm88Data[2] == 0x15)
1118 {
1119 nanoD2 = 0x15;
1120 rdr_log_dbg(reader, D_READER, "ECM: nano D2 0x15");
1121 }
1122
1123 // use the d2 arguments to get the key # to be used
1124 int32_t len = ecm88Data[1] + 2;
1125 D2KeyID = ecm88Data[3];
1126 ecm88Data += len;
1127 ecm88Len -= len;
1128 curEcm88len -= len;
1129 hasD2 = 1;
1130 }
1131 else
1132 {
1133 hasD2 = 0;
1134 }
1135
1136 // 40 07 03 0b 00 -> nano 40, len =7 ident 030B00 (tntsat), key #0 <== we're pointing here
1137 // 09 -> use key #9
1138 // 05 67 00
1139 if((ecm88Data[0] == 0x90 || ecm88Data[0] == 0x40) && (ecm88Data[1] == 0x03 || ecm88Data[1] == 0x07))
1140 {
1141 uint8_t ident[3], keynr;
1142 uint8_t *ecmf8Data = 0;
1143 int32_t ecmf8Len = 0;
1144
1145 nanoLen = ecm88Data[1] + 2;
1146 keynr = ecm88Data[4] & 0x0F;
1147
1148 // 40 07 03 0b 00 -> nano 40, len =7 ident 030B00 (tntsat), key #0 <== we're pointing here
1149 // 09 -> use key #9
1150 if(nanoLen > 5)
1151 {
1152 curnumber_ecm = (ecm88Data[6] << 8) | (ecm88Data[7]);
1153 rdr_log_dbg(reader, D_READER, "checking if the ecm number (%x) match the card one (%x)", curnumber_ecm, csystem_data->last_geo.number_ecm);
1154 // if we have an ecm number we check it.
1155 // we can't assume that if the nano len is 5 or more we have an ecm number
1156 // as some card don't support this
1157 if(csystem_data->last_geo.number_ecm > 0)
1158 {
1159 if(csystem_data->last_geo.number_ecm == curnumber_ecm && !(ecm88Data[nanoLen - 1] == 0x01))
1160 {
1161 keynr = ecm88Data[5];
1162 rdr_log_dbg(reader, D_READER, "keyToUse = %02x, ECM ending with %02x", ecm88Data[5], ecm88Data[nanoLen - 1]);
1163 }
1164 else
1165 {
1166 if(ecm88Data[nanoLen - 1] == 0x01)
1167 {
1168 rdr_log_dbg(reader, D_READER, "Skip ECM ending with = %02x for ecm number (%x) for provider %02x%02x%02x",
1169 ecm88Data[nanoLen - 1], curnumber_ecm, ecm88Data[2], ecm88Data[3], ecm88Data[4]);
1170 }
1171 rdr_log_dbg(reader, D_READER, "Skip ECM ending with = %02x for ecm number (%x)", ecm88Data[nanoLen - 1], curnumber_ecm);
1172 ecm88Data = nextEcm;
1173 ecm88Len -= curEcm88len;
1174 continue; // loop to next ecm
1175 }
1176 }
1177 else // long ecm but we don't have an ecm number so we have to try them all.
1178 {
1179 keynr = ecm88Data[5];
1180 rdr_log_dbg(reader, D_READER, "keyToUse = %02x", ecm88Data[5]);
1181 }
1182 }
1183
1184 memcpy(ident, &ecm88Data[2], sizeof(ident));
1185 provid = b2i(3, ident);
1186 ident[2] &= 0xF0;
1187
1188 if(hasD2 && reader->aes_list)
1189 {
1190 // check that we have the AES key to decode the CW
1191 // if not there is no need to send the ecm to the card
1192 if(!aes_present(reader->aes_list, 0x500, (uint32_t)(provid & 0xFFFFF0) , D2KeyID))
1193 {
1194 return ERROR;
1195 }
1196 }
1197
1198 if(!chk_prov(reader, ident, keynr))
1199 {
1200 rdr_log_dbg(reader, D_READER, "ECM: provider or key not found on card");
1201 snprintf(ea->msglog, MSGLOGSIZE, "provider(%02x%02x%02x) or key(%d) not found on card", ident[0], ident[1], ident[2], keynr);
1202 return ERROR;
1203 }
1204
1205 ecm88Data += nanoLen;
1206 ecm88Len -= nanoLen;
1207 curEcm88len -= nanoLen;
1208
1209 // DE04
1210 if(ecm88Data[0] == 0xDE && ecm88Data[1] == 0x04)
1211 {
1212 memcpy(DE04, &ecm88Data[0], 6);
1213 ecm88Data += 6;
1214 }
1215
1216 // E0 (seen so far in logs: E0020002 or E0022002, but not in all cases delivers invalid cw so just detect!)
1217 if(ecm88Data[0] == 0xE0 && ecm88Data[1] == 0x02)
1218 {
1219 rdr_log_dbg(reader, D_READER,"[viaccess-reader] nano E0 ECM detected!");
1220 hasE0=1;
1221 }
1222
1223 if(csystem_data->last_geo.provid != provid)
1224 {
1225 csystem_data->last_geo.provid = provid;
1226 csystem_data->last_geo.geo_len = 0;
1227 csystem_data->last_geo.geo[0] = 0;
1228 write_cmd(insa4, ident); // set provider
1229 }
1230
1231 // Nano D2 0x0b, 0x0f, 0x13 -> pre AES decrypt CW
1232 if(hasD2 && (nanoD2 == 0x0b|| nanoD2 == 0x0f|| nanoD2 == 0x13))
1233 {
1234 uint8_t *ecm88DataCW = ecm88Data;
1235 int32_t cwStart = 0;
1236 //int32_t cwStartRes = 0;
1237 int32_t must_exit = 0;
1238 // find CW start
1239 while(cwStart < curEcm88len - 1 && !must_exit)
1240 {
1241 if(ecm88Data[cwStart] == 0xEA && ecm88Data[cwStart + 1] == 0x10)
1242 {
1243 ecm88DataCW = ecm88DataCW + cwStart + 2;
1244 must_exit = 1;
1245 }
1246 cwStart++;
1247 }
1248
1249 if(nanoD2 == 0x0f)
1250 {
1251 hdSurEncPhase1_D2_0F_11(ecm88DataCW);
1252 hdSurEncPhase2_D2_0F_11(ecm88DataCW);
1253 }
1254
1255 if(nanoD2 == 0x13)
1256 {
1257 hdSurEncPhase1_D2_13_15(ecm88DataCW);
1258 }
1259
1260 // use AES from list to decrypt CW
1261 rdr_log_dbg(reader, D_READER, "Decoding CW : using AES key id %d for provider %06x", D2KeyID, (provid & 0xFFFFF0));
1262 if(aes_decrypt_from_list(reader->aes_list, 0x500, (uint32_t)(provid & 0xFFFFF0), D2KeyID, &ecm88DataCW[0], 16) == 0)
1263 {
1264 snprintf(ea->msglog, MSGLOGSIZE, "Missing AES key(%d)[aka E%X]",D2KeyID, D2KeyID);
1265 }
1266
1267 if(nanoD2 == 0x0f)
1268 {
1269 hdSurEncPhase1_D2_0F_11(ecm88DataCW);
1270 }
1271
1272 if(nanoD2 == 0x13)
1273 {
1274 hdSurEncPhase2_D2_13_15(ecm88DataCW);
1275 }
1276 }
1277
1278 while(ecm88Len > 1 && ecm88Data[0] < 0xA0)
1279 {
1280 nanoLen = ecm88Data[1] + 2;
1281 if(!ecmf8Data)
1282 {
1283 ecmf8Data = (uint8_t *)ecm88Data;
1284 }
1285 ecmf8Len += nanoLen;
1286 ecm88Len -= nanoLen;
1287 curEcm88len -= nanoLen;
1288 ecm88Data += nanoLen;
1289 }
1290
1291 if(ecmf8Len)
1292 {
1293 if(csystem_data->last_geo.geo_len != ecmf8Len || memcmp(csystem_data->last_geo.geo, ecmf8Data, csystem_data->last_geo.geo_len))
1294 {
1295 memcpy(csystem_data->last_geo.geo, ecmf8Data, ecmf8Len);
1296 csystem_data->last_geo.geo_len = ecmf8Len;
1297 insf8[3] = keynr;
1298 insf8[4] = ecmf8Len;
1299 write_cmd(insf8, ecmf8Data);
1300 }
1301 }
1302 ins88[2] = ecmf8Len ? 1 : 0;
1303 ins88[3] = keynr;
1304 ins88[4] = (curEcm88len > 0xFF) ? 0x00 : curEcm88len;
1305 //
1306 // we should check the nano to make sure the ecm is valid
1307 // we should look for at least 1 E3 nano, 1 EA nano and the F0 signature nano
1308 //
1309 // DE04
1310 if(DE04[0] == 0xDE)
1311 {
1312 uint32_t l = curEcm88len - 6;
1313 if(l > MAX_ECM_SIZE || curEcm88len <= 6) //don't known if this is ok...
1314 {
1315 rdr_log(reader, "ecm invalid/too long! len=%d", curEcm88len);
1316 return ERROR;
1317 }
1318 memcpy(DE04 + 6, (uint8_t *)ecm88Data, l);
1319 write_cmd(ins88, DE04); // request dcw
1320 }
1321 else
1322 {
1323 write_cmd(ins88, (uint8_t *)ecm88Data); // request dcw
1324 }
1325
1326 write_cmd(insc0, NULL); // read dcw
1327 switch(cta_res[0])
1328 {
1329 case 0xe8: // even
1330 if(cta_res[1] == 8)
1331 {
1332 memcpy(ea->cw, cta_res + 2, 8);
1333 rc = 1;
1334 } break;
1335
1336 case 0xe9: // odd
1337 if(cta_res[1] == 8)
1338 {
1339 memcpy(ea->cw + 8, cta_res + 2, 8);
1340 rc = 1;
1341 } break;
1342
1343 case 0xea: // complete
1344 if(cta_res[1] == 16)
1345 {
1346 memcpy(ea->cw, cta_res + 2, 16);
1347 rc = 1;
1348 } break;
1349
1350 default :
1351 ecm88Data = nextEcm;
1352 ecm88Len -= curEcm88len;
1353 rdr_log_dbg(reader, D_READER, "Error: card respondend %02X %02X, trying next ECM", cta_res[0], cta_res[1]);
1354 snprintf(ea->msglog, MSGLOGSIZE, "key to use is not the current one, trying next ECM");
1355 }
1356 }
1357 else
1358 {
1359 //ecm88Data=nextEcm;
1360 //ecm88Len-=curEcm88len;
1361 rdr_log_dbg(reader, D_READER, "ECM: Unknown ECM type");
1362 snprintf(ea->msglog, MSGLOGSIZE, "Unknown ECM type");
1363 return ERROR; /*Lets interupt the loop and exit, because we don't know this ECM type.*/
1364 }
1365 }
1366
1367 // Nano D2 0d, 11, 15 -> post AES decrypt CW
1368
1369 if(hasD2 && !dcw_crc(ea->cw) && (nanoD2 == 0x0d || nanoD2 == 0x11 || nanoD2 == 0x15))
1370 {
1371 if(nanoD2 == 0x11)
1372 {
1373 hdSurEncPhase1_D2_0F_11(ea->cw);
1374 hdSurEncPhase2_D2_0F_11(ea->cw);
1375 }
1376
1377 if(nanoD2 == 0x15)
1378 {
1379 hdSurEncPhase1_D2_13_15(ea->cw);
1380 }
1381 rdr_log_dbg(reader, D_READER, "Decoding CW : using AES key id %d for provider %06x", D2KeyID, (provid & 0xFFFFF0));
1382 rc = aes_decrypt_from_list(reader->aes_list, 0x500, (uint32_t)(provid & 0xFFFFF0), D2KeyID, ea->cw, 16);
1383
1384 if(rc == 0)
1385 {
1386 snprintf(ea->msglog, MSGLOGSIZE, "Missing AES key(%d)[aka E%X]",D2KeyID, D2KeyID);
1387 }
1388
1389 if(nanoD2 == 0x11)
1390 {
1391 hdSurEncPhase1_D2_0F_11(ea->cw);
1392 }
1393
1394 if(nanoD2 == 0x15)
1395 {
1396 hdSurEncPhase2_D2_13_15(ea->cw);
1397 }
1398 }
1399
1400 if (hasE0)
1401 {
1402 if (reader->initCA28)
1403 {
1404 rdr_log_dbg(reader, D_READER, "Decrypting nano E0 encrypted cw.");
1405 uint8_t returnedcw[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1406 memcpy(returnedcw,ea->cw,16);
1407
1408 // Processing 3DES
1409 // Processing even cw
1410 des(returnedcw, reader->key_schedule1, 0); // decrypt
1411 des(returnedcw, reader->key_schedule2, 1); // crypt
1412 des(returnedcw, reader->key_schedule1, 0); // decrypt
1413
1414 // Processing odd cw
1415 des(returnedcw + 8, reader->key_schedule1, 0); // decrypt
1416 des(returnedcw + 8, reader->key_schedule2, 1); // crypt
1417 des(returnedcw + 8, reader->key_schedule1, 0); // decrypt
1418
1419 // returning value
1420 memcpy(ea->cw,returnedcw, 16);
1421 }
1422 else
1423 {
1424 snprintf(ea->msglog, MSGLOGSIZE, "nano E0 detected, no valid boxkey / deskey defined: no decoding");
1425 }
1426 }
1427 return (rc ? OK : ERROR);
1428}
1429
1430static int32_t viaccess_get_emm_type(EMM_PACKET *ep, struct s_reader *rdr)
1431{
1432 uint32_t provid = 0;
1433 rdr_log_dbg(rdr, D_EMM, "Entered viaccess_get_emm_type ep->emm[0]=%02x", ep->emm[0]);
1434
1435 if(ep->emm[3] == 0x90 && ep->emm[4] == 0x03)
1436 {
1437 provid = b2i(3, ep->emm + 5);
1438 provid &= 0xFFFFF0;
1439 i2b_buf(4, provid, ep->provid);
1440 }
1441
1442 switch(ep->emm[0])
1443 {
1444 case 0x88:
1445 ep->type = UNIQUE;
1446 memset(ep->hexserial, 0, 8);
1447 memcpy(ep->hexserial, ep->emm + 4, 4);
1448 rdr_log_dbg(rdr, D_EMM, "UNIQUE");
1449 if(!is_network_reader(rdr))
1450 {
1451 return (!memcmp(rdr->hexserial + 1, ep->hexserial, 4)); // local reader
1452 }
1453 else
1454 {
1455 return 1; // let server decide!
1456 }
1457
1458 case 0x8A:
1459 case 0x8B:
1460 ep->type = GLOBAL;
1461 rdr_log_dbg(rdr, D_EMM, "GLOBAL");
1462 return 1;
1463
1464 case 0x8C:
1465 case 0x8D:
1466 ep->type = SHARED;
1467 rdr_log_dbg(rdr, D_EMM, "SHARED (part)");
1468 // We need those packets to pass otherwise we would never
1469 // be able to complete EMM reassembly
1470 return 1;
1471
1472 case 0x8E:
1473 ep->type = SHARED;
1474 rdr_log_dbg(rdr, D_EMM, "SHARED");
1475 memset(ep->hexserial, 0, 8);
1476 memcpy(ep->hexserial, ep->emm + 3, 3);
1477
1478 // local reader
1479 int8_t i;
1480 for(i = 0; i < rdr->nprov; i++)
1481 {
1482 if(!memcmp(&rdr->prid[i][2], ep->hexserial+1, 2))
1483 {
1484 return 1;
1485 }
1486 return (!memcmp(&rdr->sa[0][0], ep->hexserial, 3));
1487 } /* fallthrough */
1488
1489 default:
1490 ep->type = UNKNOWN;
1491 rdr_log_dbg(rdr, D_EMM, "UNKNOWN");
1492 return 1;
1493 }
1494}
1495
1496static int32_t viaccess_get_emm_filter(struct s_reader *rdr, struct s_csystem_emm_filter **emm_filters, unsigned int *filter_count)
1497{
1498 if(*emm_filters == NULL)
1499 {
1500 bool network = is_network_reader(rdr);
1501 int8_t device_emm = ((rdr->deviceemm > 0) ? 1 : 0); // set to 1 if device specific emms should be catched too
1502 const unsigned int max_filter_count = 4 + ((device_emm != 0 && rdr->nprov > 0) ? 1:0) + (3 * ((rdr->nprov > 0) ? (rdr->nprov - 1) : 0));
1503
1504 if(!cs_malloc(emm_filters, max_filter_count * sizeof(struct s_csystem_emm_filter)))
1505 {
1506 return ERROR;
1507 }
1508
1509 struct s_csystem_emm_filter *filters = *emm_filters;
1510 *filter_count = 0;
1511
1512 int32_t idx = 0;
1513 int32_t prov;
1514
1515 if(rdr->nprov > 0 && device_emm == 1)
1516 {
1517 filters[idx].type = EMM_GLOBAL; // 8A or 8B no reassembly needed!
1518 filters[idx].enabled = 1;
1519 filters[idx].filter[0] = 0x8A;
1520 filters[idx].mask[0] = 0xFE;
1521 filters[idx].filter[3] = 0x80; // device specific emms
1522 filters[idx].mask[3] = 0x80;
1523 idx++;
1524 }
1525
1526 // shared are most important put them on top, define first since viaccess produces a lot of filters!
1527 for(prov = 0; (prov < rdr->nprov); prov++)
1528 {
1529 if((rdr->prid[prov][2] &0xF0) == 0xF0) // skip this not useful provider
1530 {
1531 continue;
1532 }
1533
1534 filters[idx].type = EMM_SHARED; // 8C or 8D always first part of shared, second part delivered by 8E!
1535 filters[idx].enabled = 1;
1536 filters[idx].filter[0] = 0x8C;
1537 filters[idx].mask[0] = 0xFE;
1538 if(rdr->nprov > 0)
1539 {
1540 memcpy(&filters[idx].filter[4], &rdr->prid[prov][2], 2);
1541 filters[idx].mask[4] = 0xFF;
1542 filters[idx].mask[5] = 0xF0; // ignore last digit since this is key on card indicator!
1543 }
1544 idx++;
1545
1546 filters[idx].type = EMM_SHARED; // 8E second part reassembly with 8c/8d needed!
1547 filters[idx].enabled = 1;
1548 filters[idx].filter[0] = 0x8E;
1549 filters[idx].mask[0] = 0xFF;
1550 if(rdr->nprov > 0)
1551 {
1552 memcpy(&filters[idx].filter[1], &rdr->sa[prov][0], 3);
1553 memset(&filters[idx].mask[1], 0xFF, 3);
1554 }
1555 idx++;
1556 }
1557
1558 // globals are less important, define last since viaccess produces a lot of filters!
1559 for(prov = 0; (prov < rdr->nprov); prov++)
1560 {
1561 if((rdr->prid[prov][2] &0xF0) == 0xF0) // skip this not useful provider
1562 {
1563 continue;
1564 }
1565
1566 filters[idx].type = EMM_GLOBAL; // 8A or 8B no reassembly needed!
1567 filters[idx].enabled = 1;
1568 filters[idx].filter[0] = 0x8A;
1569 filters[idx].mask[0] = 0xFE;
1570 if(rdr->nprov > 0)
1571 {
1572 memcpy(&filters[idx].filter[4], &rdr->prid[prov][2], 2);
1573 filters[idx].mask[4] = 0xFF;
1574 filters[idx].mask[5] = 0xF0; // ignore last digit since this is key on card indicator!
1575 }
1576 else if (device_emm == 0)
1577 {
1578 filters[idx].filter[3] = 0x00; // additional filter to cancel device specific emms
1579 filters[idx].mask[3] = 0x80;
1580 }
1581 idx++;
1582 }
1583
1584 filters[idx].type = EMM_UNIQUE;
1585 filters[idx].enabled = 1;
1586 filters[idx].filter[0] = 0x88;
1587 filters[idx].mask[0] = 0xFF;
1588 if(!network) // network has only 3 digits out of 4
1589 {
1590 memcpy(&filters[idx].filter[1], rdr->hexserial + 1, 4);
1591 memset(&filters[idx].mask[1], 0xFF, 4);
1592 }
1593 else
1594 {
1595 memcpy(&filters[idx].filter[1], rdr->hexserial + 1, 3);
1596 memset(&filters[idx].mask[1], 0xFF, 3);
1597 }
1598 idx++;
1599
1600 *filter_count = idx;
1601 }
1602
1603 return OK;
1604}
1605
1606static int32_t viaccess_do_emm(struct s_reader *reader, EMM_PACKET *ep)
1607{
1608 def_resp;
1609 static const uint8_t insa4[] = { 0xca, 0xa4, 0x04, 0x00, 0x03 }; // set provider id
1610 uint8_t insf0[] = { 0xca, 0xf0, 0x00, 0x01, 0x22 }; // set adf
1611 uint8_t insf4[] = { 0xca, 0xf4, 0x00, 0x01, 0x00 }; // set adf, encrypted
1612 uint8_t ins18[] = { 0xca, 0x18, 0x01, 0x01, 0x00 }; // set subscription
1613 uint8_t ins1c[] = { 0xca, 0x1c, 0x01, 0x01, 0x00 }; // set subscription, encrypted
1614 struct viaccess_data *csystem_data = reader->csystem_data;
1615
1616 int32_t emmdatastart = 7;
1617
1618 if (ep->emm[1] == 0x01) // emm from cccam
1619 {
1620 emmdatastart = 12;
1621 ep->emm[1] = 0x70; // (& 0x0f) of this byte is length, so 0x01 would increase the length by 256
1622 ep->emm[2] -= 1;
1623 if (ep->type == SHARED || ep->type == GLOBAL) // build missing 0x90 nano from provider at serial position
1624 {
1625 memcpy(ep->emm + 7, ep->emm + 3, 3);
1626 ep->emm[5] = 0x90;
1627 ep->emm[6] = 0x03;
1628 ep->emm[9] |= 0x01;
1629 ep->emm[10] = 0x9E;
1630 ep->emm[11] = 0x20;
1631 emmdatastart = 5;
1632 }
1633 }
1634
1635 if(ep->type == UNIQUE)
1636 {
1637 emmdatastart++;
1638 }
1639
1640 if(ep->type == GLOBAL && emmdatastart == 7)
1641 {
1642 emmdatastart -= 4;
1643 }
1644
1645 int32_t emmLen = SCT_LEN(ep->emm) - emmdatastart;
1646 int32_t rc = 0;
1647
1648 rdr_log_dump(reader, ep->emm, emmLen + emmdatastart, "RECEIVED EMM VIACCESS");
1649
1650 int32_t emmUpToEnd;
1651 uint8_t *emmParsed = ep->emm + emmdatastart;
1652 int32_t provider_ok = 0;
1653 uint32_t emm_provid = 0;
1654 uint8_t keynr = 0;
1655 int32_t ins18Len = 0;
1656 uint8_t ins18Data[512];
1657 uint8_t insData[512];
1658 uint8_t *nano81Data = 0;
1659 uint8_t *nano91Data = 0;
1660 uint8_t *nano92Data = 0;
1661 uint8_t *nano9EData = 0;
1662 uint8_t *nanoF0Data = 0;
1663 uint8_t *nanoA9Data = 0;
1664
1665 for(emmUpToEnd = emmLen; (emmParsed[1] != 0) && (emmUpToEnd > 0); emmUpToEnd -= (2 + emmParsed[1]), emmParsed += (2 + emmParsed[1]))
1666 {
1667 rdr_log_dump(reader, emmParsed, emmParsed[1] + 2, "NANO");
1668
1669 if(emmParsed[0] == 0x90 && emmParsed[1] == 0x03)
1670 {
1671 /* identification of the service operator */
1672
1673 uint8_t soid[3], ident[3], i;
1674
1675 for(i = 0; i < 3; i++)
1676 {
1677 soid[i] = ident[i] = emmParsed[2 + i];
1678 }
1679 ident[2] &= 0xF0;
1680 emm_provid = b2i(3, ident);
1681 keynr = soid[2] & 0x0F;
1682
1683 if(chk_prov(reader, ident, keynr))
1684 {
1685 provider_ok = 1;
1686 }
1687 else
1688 {
1689 rdr_log(reader, "EMM: ignored since provider or key not present on card (%x, %x)", emm_provid, keynr);
1690 return SKIPPED;
1691 }
1692
1693 // check if the provider changes. If yes, set the new one. If not, don't... card will return an error if we do.
1694 if(csystem_data->last_geo.provid != emm_provid)
1695 {
1696 write_cmd(insa4, ident);
1697 if(cta_res[cta_lr - 2] != 0x90 || cta_res[cta_lr - 1] != 0x00)
1698 {
1699 rdr_log_dump(reader, insa4, 5, "set provider cmd:");
1700 rdr_log_dump(reader, soid, 3, "set provider data:");
1701 rdr_log(reader, "update error: %02X %02X", cta_res[cta_lr - 2], cta_res[cta_lr - 1]);
1702 return ERROR;
1703 }
1704 }
1705 // as we are maybe changing the used provider, clear the cache, so the next ecm will re-select the correct one
1706 csystem_data->last_geo.provid = 0;
1707 csystem_data->last_geo.geo_len = 0;
1708 csystem_data->last_geo.geo[0] = 0;
1709
1710 }
1711 else if(emmParsed[0] == 0x9e && emmParsed[1] == 0x20)
1712 {
1713 /* adf */
1714
1715 if(!nano91Data)
1716 {
1717 /* adf is not crypted, so test it */
1718
1719 uint8_t custwp;
1720 uint8_t *afd;
1721
1722 custwp = reader->sa[0][3];
1723 afd = (uint8_t *)emmParsed + 2;
1724
1725 if(afd[31 - custwp / 8] & (1 << (custwp & 7)))
1726 {
1727 rdr_log_dbg(reader, D_READER, "emm for our card %08X", b2i(4, &reader->sa[0][0]));
1728 }
1729 else
1730 {
1731 rdr_log_dbg(reader, D_READER, "emm not suitable for our card %08X", b2i(4, &reader->sa[0][0]));
1732 return SKIPPED;
1733 }
1734 }
1735
1736 // memorize
1737 nano9EData = emmParsed;
1738
1739 }
1740 else if(emmParsed[0] == 0x81)
1741 {
1742 nano81Data = emmParsed;
1743 }
1744 else if(emmParsed[0] == 0x91 && emmParsed[1] == 0x08)
1745 {
1746 nano91Data = emmParsed;
1747 }
1748 else if(emmParsed[0] == 0x92 && emmParsed[1] == 0x08)
1749 {
1750 nano92Data = emmParsed;
1751 }
1752 else if(emmParsed[0] == 0xF0 && emmParsed[1] == 0x08)
1753 {
1754 nanoF0Data = emmParsed;
1755 }
1756 else if(emmParsed[0] == 0xD8 && emmParsed[2] == 0x45)
1757 {
1758 uint8_t pos = 4 + emmParsed[3];
1759 char *tmpbuf;
1760 if(emmParsed[pos] == 0x46 && ((emmParsed[pos+1] - emmParsed[1]) == pos))
1761 {
1762 if(cs_malloc(&tmpbuf, emmParsed[pos + 1]))
1763 {
1764 cs_strncpy(tmpbuf, (char *)emmParsed + pos + 2, emmParsed[pos + 1]);
1765 rdr_log(reader, "Viaccess EMM-text: %s", tmpbuf);
1766 NULLFREE(tmpbuf);
1767 }
1768 }
1769 }
1770 else
1771 {
1772 /* other nanos */
1773 show_subs(reader, emmParsed);
1774 if(emmParsed[0] == 0xA9 && ep->type == SHARED) // check on shared (reassembled) emm if all classes are present and up to date on card: error 90 40
1775 {
1776 if(!emm_provid)
1777 {
1778 rdr_log(reader, "no provid in shared emm -> skipped!");
1779 return SKIPPED;
1780 }
1781 int8_t match = add_find_class(reader, emm_provid, emmParsed + 2, emmParsed[1], 0);
1782
1783 if(match == -2)
1784 {
1785 rdr_log(reader, "shared emm provid %06X all classes have entitlementdate already same or newer -> skipped!", emm_provid);
1786 return SKIPPED;
1787 }
1788 nanoA9Data = emmParsed;
1789 }
1790
1791 memcpy(ins18Data + ins18Len, emmParsed, emmParsed[1] + 2);
1792 ins18Len += emmParsed [1] + 2;
1793 }
1794 }
1795
1796 if(!provider_ok)
1797 {
1798 rdr_log_dbg(reader, D_READER, "provider not found in emm, continue anyway");
1799 // force key to 1...
1800 keynr = 1;
1801 ///return ERROR;
1802 }
1803
1804 if(!nanoF0Data)
1805 {
1806 rdr_log_dump(reader, ep->emm, ep->emmlen, "can't find 0xf0 in emm...");
1807 return ERROR; // error
1808 }
1809
1810 if(nano9EData)
1811 {
1812 if(!nano91Data)
1813 {
1814 // set adf
1815 insf0[3] = keynr; // key
1816 insf0[4] = nano9EData[1] + 2;
1817 write_cmd(insf0, nano9EData);
1818 if(cta_res[cta_lr - 2] != 0x90 || cta_res[cta_lr - 1] != 0x00)
1819 {
1820 rdr_log_dump(reader, insf0, 5, "set adf cmd:");
1821 rdr_log_dump(reader, nano9EData, insf0[4] , "set adf data:");
1822 rdr_log(reader, "update error: %02X %02X", cta_res[cta_lr - 2], cta_res[cta_lr - 1]);
1823 return ERROR;
1824 }
1825 }
1826 else
1827 {
1828 // set adf crypte
1829 insf4[3] = keynr; // key
1830 insf4[4] = nano91Data[1] + 2 + nano9EData[1] + 2;
1831 memcpy(insData, nano91Data, nano91Data[1] + 2);
1832 memcpy(insData + nano91Data[1] + 2, nano9EData, nano9EData[1] + 2);
1833 write_cmd(insf4, insData);
1834
1835 if((cta_res[cta_lr - 2] != 0x90 && cta_res[cta_lr - 2] != 0x91) || cta_res[cta_lr - 1] != 0x00)
1836 {
1837 rdr_log_dump(reader, insf4, 5, "set adf encrypted cmd:");
1838 rdr_log_dump(reader, insData, insf4[4], "set adf encrypted data:");
1839 rdr_log(reader, "update error: %02X %02X", cta_res[cta_lr - 2], cta_res[cta_lr - 1]);
1840 return ERROR;
1841 }
1842 }
1843 }
1844
1845 if(!nano92Data)
1846 {
1847 // send subscription
1848 ins18[2] = nano9EData ? 0x01 : 0x00; // found 9E nano ?
1849 ins18[3] = keynr; // key
1850 ins18[4] = ins18Len + nanoF0Data[1] + 2;
1851 memcpy(insData, ins18Data, ins18Len);
1852 memcpy(insData + ins18Len, nanoF0Data, nanoF0Data[1] + 2);
1853 write_cmd(ins18, insData);
1854
1855 if((cta_res[cta_lr - 2] == 0x90 || cta_res[cta_lr - 2] == 0x91) && cta_res[cta_lr - 1] == 0x00)
1856 {
1857 if(nanoA9Data)
1858 {
1859 add_find_class(reader, emm_provid, nanoA9Data + 2, nanoA9Data[1], 1);
1860 rdr_log(reader, "Your subscription data was updated.");
1861 }
1862 rc = 1; // written
1863 }
1864 else
1865 {
1866 rdr_log_dump(reader, ins18, 5, "set subscription cmd:");
1867 rdr_log_dump(reader, insData, ins18[4], "set subscription data:");
1868
1869 if(!(cta_res[cta_lr -2] == 0x90 && cta_res[cta_lr - 1] == 0x40)) // dont throw softerror 9040 in log!
1870 {
1871 rdr_log(reader, "update error: %02X %02X", cta_res[cta_lr - 2], cta_res[cta_lr - 1]);
1872 }
1873 else
1874 {
1875 rc = 2; // skipped
1876 }
1877 }
1878
1879 }
1880 else
1881 {
1882 // send subscription encrypted
1883
1884 if(!nano81Data)
1885 {
1886 rdr_log_dump(reader, ep->emm, ep->emmlen, "0x92 found, but can't find 0x81 in emm...");
1887 return ERROR; // error
1888 }
1889
1890 ins1c[2] = nano9EData ? 0x01 : 0x00; // found 9E nano ?
1891 if(ep->type == UNIQUE)
1892 {
1893 ins1c[2] = 0x02;
1894 }
1895
1896 ins1c[3] = keynr; // key
1897 ins1c[4] = nano92Data[1] + 2 + nano81Data[1] + 2 + nanoF0Data[1] + 2;
1898 memcpy(insData, nano92Data, nano92Data[1] + 2);
1899 memcpy(insData + nano92Data[1] + 2, nano81Data, nano81Data[1] + 2);
1900 memcpy(insData + nano92Data[1] + 2 + nano81Data[1] + 2, nanoF0Data, nanoF0Data[1] + 2);
1901 write_cmd(ins1c, insData);
1902
1903 if((cta_res[cta_lr - 2] == 0x90 || cta_res[cta_lr - 2] == 0x91) && (cta_res[cta_lr - 1] == 0x00 || cta_res[cta_lr - 1] == 0x08))
1904 {
1905 rdr_log(reader, "update successfully written");
1906 }
1907 rc = 1;
1908 }
1909
1910 return rc;
1911}
1912
1913static int32_t viaccess_card_info(struct s_reader *reader)
1914{
1915 def_resp;
1916 int32_t i, l;
1917 time_t now;
1918 struct tm timeinfo;
1919 uint16_t tmpdate;
1920 uint8_t insac[] = { 0xca, 0xac, 0x00, 0x00, 0x00 }; // select data
1921 uint8_t insb8[] = { 0xca, 0xb8, 0x00, 0x00, 0x00 }; // read selected data
1922 uint8_t insa4[] = { 0xca, 0xa4, 0x00, 0x00, 0x00 }; // select issuer
1923 uint8_t insc0[] = { 0xca, 0xc0, 0x00, 0x00, 0x00 }; // read data item
1924 static const uint8_t ins24[] = { 0xca, 0x24, 0x00, 0x00, 0x09 }; // set pin
1925
1926 uint8_t cls[] = { 0x00, 0x21, 0xff, 0x9f};
1927 static const uint8_t pin[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04};
1928 struct viaccess_data *csystem_data = reader->csystem_data;
1929
1930 csystem_data->last_geo.provid = 0;
1931 csystem_data->last_geo.geo_len = 0;
1932 csystem_data->last_geo.geo[0] = 0;
1933
1934 rdr_log(reader, "card detected");
1935
1936 cs_clear_entitlement(reader); //reset the entitlements
1937
1938 // set pin
1939 write_cmd(ins24, pin);
1940
1941 insac[2] = 0xa4;
1942 write_cmd(insac, NULL); // request unique id
1943 insb8[4] = 0x07;
1944 write_cmd(insb8, NULL); // read unique id
1945 rdr_log_sensitive(reader, "serial: {%llu}", (unsigned long long) b2ll(5, cta_res + 2));
1946
1947 insa4[2] = 0x00;
1948 write_cmd(insa4, NULL); // select issuer 0
1949
1950 for(i = 1; (cta_res[cta_lr - 2] == 0x90) && (cta_res[cta_lr - 1] == 0); i++)
1951 {
1952 bool added = false;
1953 uint32_t l_provid, l_sa;
1954 uint8_t l_name[64];
1955 insc0[4] = 0x1a;
1956 write_cmd(insc0, NULL); // show provider properties
1957 cta_res[2] &= 0xF0;
1958 l_provid = b2i(3, cta_res);
1959
1960 insac[2] = 0xa5;
1961 write_cmd(insac, NULL); // request sa
1962 insb8[4] = 0x06;
1963 write_cmd(insb8, NULL); // read sa
1964 l_sa = b2i(4, cta_res + 2);
1965
1966 insac[2] = 0xa7;
1967 write_cmd(insac, NULL); // request name
1968 insb8[4] = 0x02;
1969 write_cmd(insb8, NULL); // read name nano + len
1970 l = cta_res[1];
1971 insb8[4] = l;
1972 write_cmd(insb8, NULL); // read name
1973 cta_res[l] = 0;
1974 trim((char *)cta_res);
1975
1976 if(cta_res[0])
1977 {
1978 snprintf((char *)l_name, sizeof(l_name), ", name: %.55s", cta_res);
1979 }
1980 else
1981 {
1982 l_name[0] = 0;
1983 }
1984
1985 // read GEO
1986 insac[2] = 0xa6;
1987 write_cmd(insac, NULL); // request GEO
1988 insb8[4] = 0x02;
1989 write_cmd(insb8, NULL); // read GEO nano + len
1990 l = cta_res[1];
1991 char tmp[l * 3 + 1];
1992 insb8[4] = l;
1993 write_cmd(insb8, NULL); // read geo
1994 rdr_log_sensitive(reader, "provider: %d, id: {%06X%s}, sa: {%08X}, geo: %s", i, l_provid, l_name, l_sa, (l < 4) ? "empty" : cs_hexdump(1, cta_res, l, tmp, sizeof(tmp)));
1995
1996 // read classes subscription
1997 insac[2] = 0xa9;
1998 insac[4] = 4;
1999 if(!reader->read_old_classes)
2000 {
2001 now = time(NULL) - (24*60*60);
2002 cs_gmtime_r(&now, &timeinfo);
2003 tmpdate = timeinfo.tm_mday | ((timeinfo.tm_mon + 1) << 5) | ((timeinfo.tm_year - 80) << 9);
2004 cls[0] = tmpdate >> 8;
2005 cls[1] = tmpdate & 0xff;
2006 }
2007 write_cmd(insac, cls); // request class subs
2008
2009 while((cta_res[cta_lr - 2] == 0x90) && (cta_res[cta_lr - 1] == 0))
2010 {
2011 insb8[4] = 0x02;
2012 write_cmd(insb8, NULL); // read class subs nano + len
2013 if((cta_res[cta_lr - 2] == 0x90) && (cta_res[cta_lr - 1] == 0))
2014 {
2015 l = cta_res[1];
2016 insb8[4] = l;
2017 write_cmd(insb8, NULL); // read class subs
2018 if((cta_res[cta_lr - 2] == 0x90) && (cta_res[cta_lr - 1] == 0x00 || cta_res[cta_lr - 1] == 0x08))
2019 {
2020 show_class(reader, NULL, l_provid, cta_res, cta_lr - 2);
2021 added = true;
2022 }
2023 }
2024 }
2025
2026 if(!added)
2027 {
2028 // add entitlement info for provid without class
2029 cs_add_entitlement(reader, reader->caid, l_provid, 0, 0, 0, 0, 5, 1);
2030 }
2031
2032 insac[4] = 0;
2033 insa4[2] = 0x02;
2034 write_cmd(insa4, NULL); // select next provider
2035 }
2036 //return ERROR;
2037 // Start process init CA 28
2038 reader->initCA28=0;
2039 int32_t lenboxkey = reader->boxkey_length;
2040 int32_t lendeskey = reader->des_key_length;
2041 if ((lenboxkey >= 4) && (lendeskey > 0))
2042 {
2043 uint8_t ins28[] = { 0xCA, 0x28, 0x00, 0x00, 0x04 }; //Init for nanoE0 ca28
2044 ins28[4] = (uint8_t) lenboxkey;
2045 uint8_t ins28_data[4];
2046 memcpy(ins28_data, reader->boxkey, 4);
2047 write_cmd(ins28, ins28_data); // unlock card to reply on E002xxyy
2048
2049 if((cta_res[cta_lr - 2] == 0x90) && (cta_res[cta_lr - 1] == 0))
2050 {
2051 rdr_log(reader, "CA 28 initialisation successful!");
2052 // init 3DES key
2053 des_set_key(reader->des_key, reader->key_schedule1);
2054 des_set_key(reader->des_key+8, reader->key_schedule2);
2055 reader->initCA28=1;
2056 }
2057 else
2058 {
2059 rdr_log(reader, "CA 28 initialisation failed! CA 28 refused");
2060 }
2061 }
2062 //end process init CA 28
2063 return OK;
2064}
2065
2066static int32_t viaccess_reassemble_emm(struct s_reader *rdr, struct s_client *client, EMM_PACKET *ep)
2067{
2068 uint8_t *buffer = ep->emm;
2069 int16_t *len = &ep->emmlen;
2070 int32_t pos = 0, i;
2071 int16_t k;
2072 int32_t prov, provid = 0;
2073 struct emm_rass *r_emm = NULL;
2074
2075 // Viaccess
2076 if(*len > 500)
2077 {
2078 return 0;
2079 }
2080
2081 switch(buffer[0])
2082 {
2083 case 0x8c:
2084 case 0x8d:
2085 // emm-s part 1
2086 provid = b2i(3, ep->emm + 5); // extract provid from emm
2087 provid &= 0xFFFFF0; // last digit is dont care
2088 r_emm = find_rabuf(client, provid, (uint8_t) buffer[0], 1);
2089
2090 if(!r_emm)
2091 {
2092 cs_log("[viaccess] ERROR: Can't allocate EMM reassembly buffer.");
2093 return 0;
2094 }
2095
2096 if(!memcmp(&r_emm->emm, &buffer[0], *len)) // skip same shared emm, this make sure emmlen isnt replaced. emmlen = 0 means this shared emm has been used for reassembly
2097 {
2098 return 0;
2099 }
2100
2101 memset(&r_emm->emm[0], 0, sizeof(r_emm->emm)); // zero it!
2102 memcpy(&r_emm->emm[0], &buffer[0], *len); // put the fresh new shared emm
2103 r_emm->emmlen = *len; // put the emmlen indicating that this shared emm isnt being reassembled
2104 rdr_log_dump_dbg(rdr, D_EMM, r_emm->emm, r_emm->emmlen, "%s: received fresh emm-gh for provid %06X", __func__, provid);
2105 return 0;
2106
2107 case 0x8e:
2108 // emm-s part 2
2109 for(prov = 0; prov < rdr->nprov ; prov++)
2110 {
2111 if(!memcmp(&buffer[3], &rdr->sa[prov][0], 3))
2112 {
2113 //matching sa found!
2114 if(is_network_reader(rdr))
2115 {
2116 provid = b2i(4, ep->provid); // use provid from emm since we have nothing better!
2117 provid &= 0xFFFFF0; // last digit is dont care
2118 }
2119
2120 else
2121 {
2122 provid = b2i(4, rdr->prid[prov]); // get corresponding provid from reader since there is no provid in emm payload!
2123 provid &= 0xFFFFF0; // last digit is dont care
2124 }
2125 r_emm = find_rabuf(client, provid, 0, 0); // nano = don't care, the shared 8c or 8d not been written gets returned!
2126
2127 if(!r_emm || !r_emm->emmlen)
2128 {
2129 continue; // match but no emm-gh found for this provider
2130 }
2131 else
2132 {
2133 break; // stop searching-> emm-gh found!
2134 }
2135 }
2136 }
2137
2138 if(!r_emm || !r_emm->emmlen)
2139 {
2140 return 0; // stop -> no emm-gh found!
2141 }
2142 //extract nanos from emm-gh and emm-s
2143 uint8_t emmbuf[512];
2144
2145 rdr_log_dbg(rdr, D_EMM, "%s: start extracting nanos", __func__);
2146 //extract from emm-gh
2147 for(i = 3; i < r_emm->emmlen; i += r_emm->emm[i + 1] + 2)
2148 {
2149 //copy nano (length determined by i+1)
2150 memcpy(emmbuf + pos, r_emm->emm + i, r_emm->emm[i + 1] + 2);
2151 pos += r_emm->emm[i + 1] + 2;
2152 }
2153
2154 if(buffer[2] == 0x2c)
2155 {
2156 //add 9E 20 nano + first 32 uint8_ts of emm content
2157 memcpy(emmbuf + pos, "\x9E\x20", 2);
2158 memcpy(emmbuf + pos + 2, buffer + 7, 32);
2159 pos += 34;
2160
2161 //add F0 08 nano + 8 subsequent uint8_ts of emm content
2162 memcpy(emmbuf + pos, "\xF0\x08", 2);
2163 memcpy(emmbuf + pos + 2, buffer + 39, 8);
2164 pos += 10;
2165 }
2166 else
2167 {
2168 //extract from variable emm-s
2169 for(k = 7; k < (*len); k += buffer[k + 1] + 2)
2170 {
2171 //copy nano (length determined by k+1)
2172 memcpy(emmbuf + pos, buffer + k, buffer[k + 1] + 2);
2173 pos += buffer[k + 1] + 2;
2174 }
2175 }
2176
2177 rdr_log_dump_dbg(rdr, D_EMM, buffer, *len, "%s: %s emm-s", __func__, (buffer[2] == 0x2c) ? "fixed" : "variable");
2178
2179 emm_sort_nanos(buffer + 7, emmbuf, pos);
2180 pos += 7;
2181
2182 //calculate emm length and set it on position 2
2183 buffer[2] = pos - 3;
2184
2185 rdr_log_dump_dbg(rdr, D_EMM, r_emm->emm, r_emm->emmlen, "%s: emm-gh provid %06X", __func__, provid);
2186 rdr_log_dump_dbg(rdr, D_EMM, buffer, pos, "%s: assembled emm", __func__);
2187
2188 *len = pos;
2189 r_emm->emmlen = 0; // mark this shared 8c or 8d as being used for reassembly and send to reader!
2190 break;
2191 }
2192 return 1;
2193}
2194
2195const struct s_cardsystem reader_viaccess =
2196{
2197 .desc = "viaccess",
2198 .caids = (uint16_t[]){ 0x05, 0 },
2199 .do_emm_reassembly = viaccess_reassemble_emm,
2200 .do_emm = viaccess_do_emm,
2201 .do_ecm = viaccess_do_ecm,
2202 .card_info = viaccess_card_info,
2203 .card_init = viaccess_card_init,
2204 .get_emm_type = viaccess_get_emm_type,
2205 .get_emm_filter = viaccess_get_emm_filter,
2206};
2207
2208#endif
Note: See TracBrowser for help on using the repository browser.