source: branches/merlin/src/CAM/drecrypt.c@ 532

Last change on this file since 532 was 532, checked in by smurzch2, 12 years ago

Merge drecrypt stuff in the Merlin branch.

This should merge the commits 491, 492, 497, 498, 501 and 521.

File size: 12.4 KB
Line 
1#include <time.h>
2
3#include "globals.h"
4#include "CAM/drecrypt.h"
5#include "CAM/common.h"
6
7#include "simples.h"
8#include "log.h"
9
10unsigned long long serial;
11char *card;
12static uchar provider;
13static short int mode;
14
15#define OK_RESPONSE 0x61
16#define CMD_BYTE 0x59
17
18static uchar xor (const uchar *cmd, int cmdlen)
19{
20 int i;
21 uchar checksum = 0x00;
22 for (i = 0; i < cmdlen; i++)
23 checksum ^= cmd[i];
24 return checksum;
25}
26
27#define cam_drecrypt_cmd(cmd, result, result_size) \
28{ \
29 cam_drecrypt_do_cmd(cmd, sizeof(cmd), result, sizeof(result), result_size); \
30}
31
32static int cam_drecrypt_do_cmd (const unsigned char *cmd, int cmdlen, uchar *result, ushort result_max_size, ushort *result_size)
33{
34
35 static uchar startcmd[] = { 0x80, 0xFF, 0x10, 0x01, 0x05 }; //any command starts with this,
36 //last byte is nr of bytes of the command that will be sent
37 //after the startcmd
38 //response on startcmd+cmd: = { 0x61, 0x05 } //0x61 = "OK", last byte is nr. of bytes card will send
39 static uchar reqans[] = { 0x00, 0xC0, 0x00, 0x00, 0x08 }; //after command answer has to be requested,
40 //last byte must be nr. of bytes that card has reported to send
41 uchar command[256];
42 int headerlen = sizeof (startcmd);
43 startcmd[4] = cmdlen + 3; //commandlength + type + len + checksum bytes
44 memcpy (command, startcmd, headerlen);
45 command[headerlen++] = CMD_BYTE; //type
46 command[headerlen++] = cmdlen + 1; //len = command + 1 checksum byte
47 memcpy (command + headerlen, cmd, cmdlen);
48
49 uchar checksum = ~xor (cmd, cmdlen);
50 //log_debug ("Checksum: %02x", checksum);
51 cmdlen += headerlen;
52 command[cmdlen++] = checksum;
53
54 int rc;
55 rc = cam_common_cmd2card (command, cmdlen, result, result_max_size, result_size);
56
57 if (*result_size != 2 || (result[0] != OK_RESPONSE)) {
58 log_debug ("DRECRYPT ERROR: unexpected answer from card: %s", cs_hexdump (0, result, *result_size));
59 return 0; //error
60 }
61
62 reqans[4] = result[1]; //adapt length byte
63 cam_common_cmd2card (reqans, 5, result, result_max_size, result_size);
64
65 if (result[0] != CMD_BYTE) {
66 log_debug ("DRECRYPT Unknown response: result[0] expected to be %02x, is %02x", CMD_BYTE, result[0]);
67 return 0;
68 }
69 if ((result[1] == 0x03) && (result[2] == 0xe2)) {
70 switch (result[3]) {
71 case 0xe1:
72 log_debug ("DRECRYPT checksum error: %s.", cs_hexdump (0, result, *result_size));
73 break;
74 case 0xe2:
75 log_debug ("DRECRYPT wrong provider: %s.", cs_hexdump (0, result, *result_size));
76 break;
77 case 0xec:
78 log_debug ("DRECRYPT wrong signature: %s.", cs_hexdump (0, result, *result_size));
79 break;
80 default:
81 log_debug ("DRECRYPT unknown error: %s.", cs_hexdump (0, result, *result_size));
82 break;
83 }
84 return 0; //error
85 }
86 int length_excl_leader = *result_size;
87 if ((result[*result_size - 2] == 0x90) && (result[*result_size - 1] == 0x00))
88 length_excl_leader -= 2;
89
90 checksum = ~xor (result + 2, length_excl_leader - 3);
91
92 if (result[length_excl_leader - 1] != checksum) {
93 log_debug ("DRECRYPT checksum does not match, expected %02x received %02x:%s", checksum,
94 result[length_excl_leader - 1], cs_hexdump (0, result, *result_size));
95 return 0; //error
96 }
97 return 1;
98}
99
100static int cam_drecrypt_set_provider_info()
101{
102 int i;
103 static uchar cmd59[] = { 0x59, 0x14 }; // subscriptions
104 static uchar cmd5b[] = { 0x5b, 0x00, 0x14 }; //validity dates
105 uchar result[260];
106 ushort result_size;
107
108 cmd59[1] = provider;
109 if ((cam_drecrypt_cmd (cmd59, result, &result_size))) { //ask subscription packages, returns error on 0x11 card
110 uchar pbm[32];
111 memcpy (pbm, result + 3, result_size - 6);
112 log_debug ("DRECRYPT pbm: %s", cs_hexdump (0, pbm, 32));
113
114 if (pbm[0] == 0xff)
115 log_debug ("No active packages!");
116 else
117 for (i = 0; i < 32; i++)
118 if (pbm[i] != 0xff) {
119 cmd5b[1] = i;
120 cmd5b[2] = provider;
121 cam_drecrypt_cmd (cmd5b, result, &result_size); //ask for validity dates
122
123 time_t start;
124 time_t end;
125 start = (result[3] << 24) | (result[4] << 16) | (result[5] << 8) | result[6];
126 end = (result[7] << 24) | (result[8] << 16) | (result[9] << 8) | result[10];
127
128 struct tm *temp;
129
130 temp = localtime (&start);
131 int startyear = temp->tm_year + 1900;
132 int startmonth = temp->tm_mon + 1;
133 int startday = temp->tm_mday;
134 temp = localtime (&end);
135 int endyear = temp->tm_year + 1900;
136 int endmonth = temp->tm_mon + 1;
137 int endday = temp->tm_mday;
138 log_normal ("Active package %i valid from %04i/%02i/%02i to %04i/%02i/%02i", i, startyear, startmonth, startday,
139 endyear, endmonth, endday);
140 }
141 }
142 return 1;
143}
144
145int cam_drecrypt_detect(uchar *atr, ushort atr_size)
146{
147 if (atr[0] == 0x3b && atr[1] == 0x15 && atr[2] == 0x11 && atr[3] == 0x12 && atr[4] == 0xca && atr[5] == 0x07) {
148 return 1;
149 }
150 return 0;
151}
152
153int cam_drecrypt_load_card()
154{
155 static uchar ua[] = { 0x43, 0x15 }; // get serial number (UA)
156 static uchar providers[] = { 0x49, 0x15 }; // get providers
157 int i;
158 uchar result[260];
159 ushort result_size;
160
161 provider = reader[ridx].card_atr[6];
162 uchar checksum = xor (reader[ridx].card_atr + 1, 6);
163
164 if (checksum != reader[ridx].card_atr[7]) {
165 log_debug ("DRECRYPT Warning: expected ATR checksum %02x, smartcard reports %02x", checksum, reader[ridx].card_atr[7]);
166 }
167
168 switch (reader[ridx].card_atr[6]) {
169 case 0x11:
170 card = "Tricolor Centr";
171 reader[ridx].caid[0] = 0x4ae0;
172 mode = 41;
173 break; //59 type card = MSP (74 type = ATMEL)
174 case 0x12:
175 card = "Cable TV";
176 reader[ridx].caid[0] = 0x4ae0; //TODO not sure about this one
177 mode = 41; //TODO not sure
178 break;
179 case 0x14:
180 card = "Tricolor Syberia / Platforma HD new";
181 reader[ridx].caid[0] = 0x4ae1;
182 mode = 51;
183 break; //59 type card
184 case 0x15:
185 card = "Platforma HD / DW old";
186 reader[ridx].caid[0] = 0x4ae1;
187 mode = 51;
188 break; //59 type card
189 default:
190 card = "Unknown";
191 reader[ridx].caid[0] = 0x4ae1;
192 mode = 51;
193 break;
194 }
195
196 memset (reader[ridx].prid, 0x00, 8);
197
198 static uchar cmd30[] = { 0x30, 0x81, 0x00, 0x81, 0x82, 0x03, 0x84, 0x05, 0x06, 0x87, 0x08, 0x09, 0x00, 0x81, 0x82, 0x03, 0x84, 0x05, 0x00 };
199 cam_drecrypt_cmd (cmd30, result, &result_size); //unknown command, generates error on card 0x11 and 0x14
200 /*
201response:
20259 03 E2 E3
203FE 48 */
204
205 static uchar cmd54[] = { 0x54, 0x14 }; // geocode
206 cmd54[1] = provider;
207 uchar geocode = 0;
208 if ((cam_drecrypt_cmd (cmd54, result, &result_size))) //error would not be fatal, like on 0x11 cards
209 geocode = result[3];
210
211 providers[1] = provider;
212 if (!(cam_drecrypt_cmd (providers, result, &result_size)))
213 return 0; //fatal error
214 if ((result[result_size - 2] != 0x90) || (result[result_size - 1] != 0x00))
215 return 0;
216 uchar provname[128];
217 for (i = 0; ((i < result[2] - 6) && (i < 128)); i++) {
218 provname[i] = result[6 + i];
219 if (provname[i] == 0x00)
220 break;
221 }
222 int major_version = result[3];
223 int minor_version = result[4];
224
225 ua[1] = provider;
226 cam_drecrypt_cmd (ua, result, &result_size); //error would not be fatal
227
228 int hexlength = result[1] - 2; //discard first and last byte, last byte is always checksum, first is answer code
229
230 reader[ridx].hexserial[0] = 0;
231 reader[ridx].hexserial[1] = 0;
232 memcpy (reader[ridx].hexserial + 2, result + 3, hexlength);
233
234 int low_dre_id = ((result[4] << 16) | (result[5] << 8) | result[6]) - 48608;
235 int dre_chksum = 0;
236 uchar buf[32];
237 sprintf ((char *)buf, "%i%i%08i", provider - 16, major_version + 1, low_dre_id);
238 for (i = 0; i < 32; i++) {
239 if (buf[i] == 0x00)
240 break;
241 dre_chksum += buf[i] - 48;
242 }
243
244 //cs_ri_log("type: DRECrypt, caid: %04X, serial: %llu, card: v%x",
245 log_normal ("type: DRECrypt, caid: %04X, serial: %s, dre id: %i%i%i%08i, geocode %i, card: %s v%i.%i",
246 reader[ridx].caid[0], cs_hexdump (0, reader[ridx].hexserial + 2, 4), dre_chksum, provider - 16,
247 major_version + 1, low_dre_id, geocode, card, major_version, minor_version);
248 log_normal ("Provider name:%s.", provname);
249
250
251 memset (reader[ridx].sa, 0, sizeof (reader[ridx].sa));
252 memcpy (reader[ridx].sa[0], reader[ridx].hexserial + 2, 1); //copy first byte of unique address also in shared address, because we dont know what it is...
253
254 log_debug ("DEBUG: SA = %02X%02X%02X%02X, UA = %s", reader[ridx].sa[0][0], reader[ridx].sa[0][1], reader[ridx].sa[0][2],
255 reader[ridx].sa[0][3], cs_hexdump (0, reader[ridx].hexserial + 2, 4));
256
257 //reader[ridx].nprov = 1; TODO doesnt seem necessary
258
259 if (!cam_drecrypt_set_provider_info ())
260 return 0; //fatal error
261
262 log_normal ("ready for requests");
263 return (1);
264}
265
266int cam_drecrypt_process_ecm(ECM_REQUEST * er)
267{
268 uchar result[260];
269 ushort result_size;
270 if (mode == 41) {
271 static uchar ecmcmd41[] = { 0x41,
272 0x58, 0x1f, 0x00, //fixed part, dont change
273 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, //0x01 - 0x08: next key
274 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, //0x11 - 0x18: current key
275 0x3b, 0x59, 0x11 //0x3b = keynumber, can be a value 56 ;; 0x59 number of package = 58+1 - Pay Package ;; 0x11 = provider
276 };
277 ecmcmd41[22] = provider;
278 memcpy (ecmcmd41 + 4, er->ecm + 8, 16);
279 ecmcmd41[20] = er->ecm[6]; //keynumber
280 ecmcmd41[21] = 0x58 + er->ecm[25]; //package number
281 log_debug ("DEBUG: unused ECM info front:%s", cs_hexdump (0, er->ecm, 8));
282 log_debug ("DEBUG: unused ECM info back:%s", cs_hexdump (0, er->ecm + 24, er->ecm[2] + 2 - 24));
283 if ((cam_drecrypt_cmd (ecmcmd41, result, &result_size))) { //ecm request
284 if ((result[result_size - 2] != 0x90) || (result[result_size - 1] != 0x00))
285 return 0; //exit if response is not 90 00
286 memcpy (er->cw, result + 11, 8);
287 memcpy (er->cw + 8, result + 3, 8);
288
289 return 1;
290 }
291 }
292 else {
293
294 static uchar ecmcmd51[] = { 0x51, 0x02, 0x56, 0x05, 0x00, 0x4A, 0xE3, //fixed header?
295 0x9C, 0xDA, //first three nibbles count up, fourth nibble counts down; all ECMs sent twice
296 0xC1, 0x71, 0x21, 0x06, 0xF0, 0x14, 0xA7, 0x0E, //next key?
297 0x89, 0xDA, 0xC9, 0xD7, 0xFD, 0xB9, 0x06, 0xFD, //current key?
298 0xD5, 0x1E, 0x2A, 0xA3, 0xB5, 0xA0, 0x82, 0x11, //key or signature?
299 0x14 //provider
300 };
301 memcpy (ecmcmd51 + 1, er->ecm + 5, 0x21);
302 log_debug ("DEBUG: unused ECM info front:%s", cs_hexdump (0, er->ecm, 5));
303 log_debug ("DEBUG: unused ECM info back:%s", cs_hexdump (0, er->ecm + 37, 4));
304 ecmcmd51[33] = provider; //no part of sig
305 if ((cam_drecrypt_cmd (ecmcmd51, result, &result_size))) { //ecm request
306 if ((result[result_size - 2] != 0x90) || (result[result_size - 1] != 0x00))
307 return 0; //exit if response is not 90 00
308 memcpy (er->cw, result + 11, 8);
309 memcpy (er->cw + 8, result + 3, 8);
310 return 1;
311 }
312 }
313 return 0;
314}
315
316int cam_drecrypt_process_emm(EMM_PACKET * ep)
317{
318 uchar result[260];
319 ushort result_size;
320
321 int emm_length = ((ep->emm[1] & 0x0f) << 8) + ep->emm[2];
322
323 log_ddump (ep->emm, emm_length + 3, "EMM:");
324 ep->type = ep->emm[0];
325
326 if (mode == 51) {
327 static uchar emmcmd52[0x3a];
328 emmcmd52[0] = 0x52;
329 int i;
330 for (i = 0; i < 2; i++) {
331 memcpy (emmcmd52 + 1, ep->emm + 5 + 32 + i * 56, 56);
332 emmcmd52[0x39] = provider;
333 if ((cam_drecrypt_cmd (emmcmd52, result, &result_size)))
334 if ((result[result_size - 2] != 0x90) || (result[result_size - 1] != 0x00))
335 return 0; //exit if response is not 90 00
336 }
337 }
338 else {
339 static uchar emmcmd42[] =
340 { 0x42, 0x85, 0x58, 0x01, 0xC8, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x0C, 0xBD, 0x7B, 0x07, 0x04, 0xC8,
341 0x77, 0x31, 0x95, 0xF2, 0x30, 0xB7, 0xE9, 0xEE, 0x0F, 0x81, 0x39, 0x1C, 0x1F, 0xA9, 0x11, 0x3E,
342 0xE5, 0x0E, 0x8E, 0x50, 0xA4, 0x31, 0xBB, 0x01, 0x00, 0xD6, 0xAF, 0x69, 0x60, 0x04, 0x70, 0x3A,
343 0x91,
344 0x56, 0x58, 0x11
345 };
346 memcpy (emmcmd42 + 1, ep->emm + 6, 48);
347 emmcmd42[51] = provider;
348 //emmcmd42[50] = ecmcmd42[2]; //TODO package nr could also be fixed 0x58
349 emmcmd42[50] = 0x58;
350 emmcmd42[49] = ep->emm[5]; //keynr
351 /* response:
352 59 05 A2 02 05 01 5B
353 90 00 */
354 if ((cam_drecrypt_cmd (emmcmd42, result, &result_size))) { //first emm request
355 if ((result[result_size - 2] != 0x90) || (result[result_size - 1] != 0x00))
356 return 0; //exit if response is not 90 00
357
358 memcpy (emmcmd42 + 1, ep->emm + 55, 7); //TODO OR next two lines?
359 /*memcpy (emmcmd42 + 1, ep->emm + 55, 7); //FIXME either I cant count or my EMM log contains errors
360 memcpy (emmcmd42 + 8, ep->emm + 67, 41); */
361 emmcmd42[51] = provider;
362 //emmcmd42[50] = ecmcmd42[2]; //TODO package nr could also be fixed 0x58
363 emmcmd42[50] = 0x58;
364 emmcmd42[49] = ep->emm[54]; //keynr
365 if ((cam_drecrypt_cmd (emmcmd42, result, &result_size))) { //second emm request
366 if ((result[result_size - 2] != 0x90) || (result[result_size - 1] != 0x00))
367 return 0; //exit if response is not 90 00
368 }
369 }
370 }
371 return 1; //success
372}
Note: See TracBrowser for help on using the repository browser.