source: trunk/reader-viaccess.c@ 10658

Last change on this file since 10658 was 10658, checked in by theparasol, 9 years ago

Fix: viaccess aes handling now provider independent

Thanks Pr2 for providing patch!

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