[598] | 1 | #include "globals.h"
|
---|
| 2 | #include "reader-common.h"
|
---|
[655] | 3 | #include "cscrypt/idea.h"
|
---|
[598] | 4 | #include <termios.h>
|
---|
| 5 | #include <unistd.h>
|
---|
| 6 |
|
---|
[1504] | 7 | IDEA_KEY_SCHEDULE ksSession;
|
---|
[598] | 8 | extern uchar cta_res[];
|
---|
| 9 | extern ushort cta_lr;
|
---|
[1504] | 10 | int is_pure_nagra=0;
|
---|
| 11 | int is_tiger=0;
|
---|
| 12 | int has_dt08=0;
|
---|
| 13 | int swapCW=0;
|
---|
| 14 | unsigned char rom[15];
|
---|
| 15 | unsigned char plainDT08RSA[64];
|
---|
| 16 | unsigned char IdeaCamKey[16];
|
---|
| 17 | unsigned char irdId[] = {0xff,0xff,0xff,0xff};
|
---|
| 18 | unsigned char sessi[16];
|
---|
| 19 | unsigned char signature[8];
|
---|
| 20 | unsigned char cam_state[3];
|
---|
[598] | 21 |
|
---|
| 22 | // Card Status checks
|
---|
[1528] | 23 | #define HAS_CW() ((cam_state[2]&6)==6)
|
---|
| 24 | #define RENEW_SESSIONKEY() ((cam_state[0]&128)==128 || (cam_state[0]&64)==64 || (cam_state[0]&32)==32 || (cam_state[2]&8)==8)
|
---|
| 25 | #define SENDDATETIME() (cam_state[0]&8)
|
---|
[598] | 26 | // Datatypes
|
---|
| 27 | #define DT01 0x01
|
---|
| 28 | #define IRDINFO 0x00
|
---|
| 29 | #define TIERS 0x05
|
---|
| 30 | #define DT06 0x06
|
---|
| 31 | #define CAMDATA 0x08
|
---|
| 32 |
|
---|
| 33 | #define MAX_REC 20
|
---|
[662] | 34 | #define SYSTEM_NAGRA 0x1800
|
---|
[679] | 35 | #define SYSTEM_MASK 0xFF00
|
---|
[598] | 36 |
|
---|
[1344] | 37 |
|
---|
| 38 | static time_t tier_date(ulong date, char *buf, int l)
|
---|
[598] | 39 | {
|
---|
[798] | 40 | time_t ut=870393600L+date*(24*3600);
|
---|
| 41 | if (buf)
|
---|
| 42 | {
|
---|
| 43 | struct tm *t;
|
---|
| 44 | t=gmtime(&ut);
|
---|
| 45 | snprintf(buf, l, "%04d/%02d/%02d", t->tm_year+1900, t->tm_mon+1, t->tm_mday);
|
---|
| 46 | }
|
---|
| 47 | return(ut);
|
---|
[598] | 48 | }
|
---|
| 49 |
|
---|
[1344] | 50 | static int do_cmd(unsigned char cmd, int ilen, unsigned char res, int rlen, unsigned char *data)
|
---|
[598] | 51 | {
|
---|
| 52 | /*
|
---|
| 53 | here we build the command related to the protocol T1 for ROM142 or T14 for ROM181
|
---|
| 54 | the only different that i know is the command length byte msg[4], this msg[4]+=1 by a ROM181 smartcard (_nighti_)
|
---|
| 55 | one example for the cmd$C0
|
---|
| 56 | T14 protocol: 01 A0 CA 00 00 03 C0 00 06 91
|
---|
| 57 | T1 protocol: 21 00 08 A0 CA 00 00 02 C0 00 06 87
|
---|
| 58 | */
|
---|
| 59 | int msglen=ilen+6;
|
---|
| 60 | unsigned char msg[msglen];
|
---|
[1347] | 61 | static char nagra_head[] = {0xA0, 0xCA, 0x00, 0x00};
|
---|
[598] | 62 |
|
---|
| 63 | memset(msg, 0, msglen);
|
---|
| 64 | memcpy(msg,nagra_head,4);
|
---|
| 65 | msg[4] = ilen;
|
---|
| 66 | msg[5] = cmd;
|
---|
| 67 | int dlen=ilen-2;
|
---|
| 68 | msg[6] = dlen;
|
---|
| 69 | if(data && dlen>0) memcpy(msg+7,data,dlen);
|
---|
| 70 | msg[dlen+7] = rlen;
|
---|
| 71 | if (dlen<0)
|
---|
| 72 | {
|
---|
| 73 | cs_debug("[nagra-reader] invalid data length encountered");
|
---|
[1389] | 74 | return ERROR;
|
---|
[598] | 75 | }
|
---|
[1504] | 76 | if (is_pure_nagra==1)
|
---|
[820] | 77 | {
|
---|
[1043] | 78 | msg[4]+=1;
|
---|
[820] | 79 | }
|
---|
[598] | 80 | if(!reader_cmd2icc(msg,msglen))
|
---|
| 81 | {
|
---|
[1543] | 82 | cs_sleepms(5);
|
---|
[598] | 83 | if(cta_res[0]!=res)
|
---|
| 84 | {
|
---|
| 85 | cs_debug("[nagra-reader] result not expected (%02x != %02x)",cta_res[0],res);
|
---|
[1389] | 86 | return ERROR;
|
---|
[598] | 87 | }
|
---|
| 88 | if((cta_lr-2)!=rlen)
|
---|
| 89 | {
|
---|
| 90 | cs_debug("[nagra-reader] result length expected (%d != %d)",(cta_lr-2),rlen);
|
---|
[1389] | 91 | return ERROR;
|
---|
[598] | 92 | }
|
---|
| 93 | return cta_lr;
|
---|
| 94 | }
|
---|
[1389] | 95 | return ERROR;
|
---|
[598] | 96 | }
|
---|
| 97 |
|
---|
[1344] | 98 | static void ReverseMem(unsigned char *vIn, int len)
|
---|
[598] | 99 | {
|
---|
| 100 | unsigned char temp;
|
---|
| 101 | int i;
|
---|
| 102 | for(i=0; i < (len/2); i++)
|
---|
| 103 | {
|
---|
| 104 | temp = vIn[i];
|
---|
| 105 | vIn[i] = vIn[len-i-1];
|
---|
| 106 | vIn[len-i-1] = temp;
|
---|
| 107 | }
|
---|
| 108 | }
|
---|
| 109 |
|
---|
[1347] | 110 | static void Signature(unsigned char *sig, const unsigned char *vkey,const unsigned char *msg, int len)
|
---|
[598] | 111 | {
|
---|
| 112 | IDEA_KEY_SCHEDULE ks;
|
---|
| 113 | unsigned char v[8];
|
---|
| 114 | unsigned char b200[16];
|
---|
| 115 | unsigned char b0f0[8];
|
---|
| 116 | memcpy(b200,vkey,sizeof(b200));
|
---|
| 117 | int i;
|
---|
| 118 | int j;
|
---|
| 119 | for(i=0; i<len; i+=8)
|
---|
| 120 | {
|
---|
| 121 | idea_set_encrypt_key(b200,&ks);
|
---|
| 122 | memset(v,0,sizeof(v));
|
---|
| 123 | idea_cbc_encrypt(msg+i,b0f0,8,&ks,v,IDEA_DECRYPT);
|
---|
| 124 | for(j=7; j>=0; j--) b0f0[j]^=msg[i+j];
|
---|
| 125 | memcpy(b200+0,b0f0,8);
|
---|
| 126 | memcpy(b200+8,b0f0,8);
|
---|
| 127 | }
|
---|
| 128 | memcpy(sig,b0f0,8);
|
---|
| 129 | return;
|
---|
| 130 | }
|
---|
| 131 |
|
---|
[1344] | 132 | static int CamStateRequest(void)
|
---|
[598] | 133 | {
|
---|
| 134 | if(do_cmd(0xC0,0x02,0xB0,0x06,NULL))
|
---|
| 135 | {
|
---|
[1504] | 136 | memcpy(cam_state,cta_res+3,3);
|
---|
[1529] | 137 | cs_debug("[nagra-reader] Camstate: %s",cs_hexdump (1, cam_state, 3));
|
---|
[598] | 138 | }
|
---|
| 139 | else
|
---|
| 140 | {
|
---|
| 141 | cs_debug("[nagra-reader] CamStateRequest failed");
|
---|
[1389] | 142 | return ERROR;
|
---|
[598] | 143 | }
|
---|
[1389] | 144 | return OK;
|
---|
[598] | 145 | }
|
---|
| 146 |
|
---|
[1344] | 147 | static void DateTimeCMD(void)
|
---|
[662] | 148 | {
|
---|
[1528] | 149 | if (!do_cmd(0xC8,0x02,0xB8,0x06,NULL))
|
---|
| 150 | {
|
---|
| 151 | cs_debug("[nagra-reader] DateTimeCMD failed!");
|
---|
| 152 | }
|
---|
| 153 |
|
---|
[662] | 154 | }
|
---|
| 155 |
|
---|
[1344] | 156 | static int NegotiateSessionKey_Tiger(void)
|
---|
[1043] | 157 | {
|
---|
[1083] | 158 |
|
---|
[1043] | 159 | unsigned char vFixed[] = {0,1,2,3,0x11};
|
---|
| 160 | unsigned char parte_fija[120];
|
---|
| 161 | unsigned char parte_variable[88];
|
---|
| 162 | unsigned char d1_rsa_modulo[88];
|
---|
| 163 | unsigned char d2_data[88];
|
---|
| 164 | unsigned char sign1[8];
|
---|
[1196] | 165 | unsigned char sk[16];
|
---|
[1043] | 166 | unsigned char tmp[104];
|
---|
[1162] | 167 | unsigned char idea_sig[16];
|
---|
[1196] | 168 | unsigned char random[88];
|
---|
[1043] | 169 |
|
---|
| 170 | if(!do_cmd(0xd1,0x02,0x51,0xd2,NULL))
|
---|
| 171 | {
|
---|
| 172 | cs_debug("[nagra-reader] CMD$D1 failed");
|
---|
[1389] | 173 | return ERROR;
|
---|
[1043] | 174 | }
|
---|
| 175 |
|
---|
| 176 | BN_CTX *ctx = BN_CTX_new();
|
---|
| 177 | BIGNUM *bnN = BN_CTX_get(ctx);
|
---|
| 178 | BIGNUM *bnE = BN_CTX_get(ctx);
|
---|
| 179 | BIGNUM *bnCT = BN_CTX_get(ctx);
|
---|
| 180 | BIGNUM *bnPT = BN_CTX_get(ctx);
|
---|
[1083] | 181 | BN_bin2bn(reader[ridx].rsa_mod, 120, bnN);
|
---|
[1043] | 182 | BN_bin2bn(vFixed+4, 1, bnE);
|
---|
| 183 | BN_bin2bn(&cta_res[90], 120, bnCT);
|
---|
| 184 | BN_mod_exp(bnPT, bnCT, bnE, bnN, ctx);
|
---|
| 185 | memset(parte_fija, 0, 120);
|
---|
| 186 | BN_bn2bin(bnPT, parte_fija + (120-BN_num_bytes(bnPT)));
|
---|
| 187 | BN_CTX_end(ctx);
|
---|
| 188 | BN_CTX_free (ctx);
|
---|
| 189 |
|
---|
| 190 | cs_debug("[nagra-reader] ---------- SIG CHECK ---------------------");
|
---|
| 191 | memset(tmp,0, 104);
|
---|
[1083] | 192 | memcpy(tmp+4, parte_fija+11, 100);
|
---|
[1162] | 193 | memset(idea_sig, 0x37, 16);
|
---|
| 194 | Signature(sign1, idea_sig, tmp, 104);
|
---|
[1043] | 195 | cs_debug("[nagra-reader] sign1: %s", cs_hexdump (0, sign1, 8));
|
---|
| 196 | cs_debug("[nagra-reader] sign2: %s", cs_hexdump (0, parte_fija+111, 8));
|
---|
| 197 | if (!memcmp (parte_fija+111, sign1, 8)==0)
|
---|
| 198 | {
|
---|
| 199 | cs_debug("[nagra-reader] signature check nok");
|
---|
[1083] | 200 | cs_debug("[nagra-reader] ------------------------------------------");
|
---|
[1389] | 201 | return ERROR;
|
---|
[1043] | 202 | }
|
---|
[1083] | 203 | cs_debug("[nagra-reader] signature check ok");
|
---|
[1043] | 204 | cs_debug("[nagra-reader] ------------------------------------------");
|
---|
| 205 |
|
---|
[1259] | 206 | memcpy(reader[ridx].hexserial+2, parte_fija+15, 4);
|
---|
[1504] | 207 | memcpy(irdId, parte_fija+19, 4);
|
---|
[1083] | 208 | memcpy(d1_rsa_modulo,parte_fija+23,88);
|
---|
| 209 |
|
---|
| 210 | ReverseMem(cta_res+2, 88);
|
---|
| 211 | BN_CTX *ctx1 = BN_CTX_new();
|
---|
| 212 | BIGNUM *bnN1 = BN_CTX_get(ctx1);
|
---|
| 213 | BIGNUM *bnE1 = BN_CTX_get(ctx1);
|
---|
| 214 | BIGNUM *bnCT1 = BN_CTX_get(ctx1);
|
---|
| 215 | BIGNUM *bnPT1 = BN_CTX_get(ctx1);
|
---|
| 216 | BN_bin2bn(d1_rsa_modulo, 88, bnN1);
|
---|
| 217 | BN_bin2bn(vFixed+4, 1, bnE1);
|
---|
| 218 | BN_bin2bn(cta_res+2, 88, bnCT1);
|
---|
| 219 | BN_mod_exp(bnPT1, bnCT1, bnE1, bnN1, ctx1);
|
---|
| 220 | memset(parte_variable, 0, 88);
|
---|
| 221 | BN_bn2bin(bnPT1, parte_variable + (88-BN_num_bytes(bnPT1)));
|
---|
| 222 | BN_CTX_end(ctx1);
|
---|
| 223 | BN_CTX_free (ctx1);
|
---|
| 224 |
|
---|
| 225 | reader[ridx].prid[0][0]=0x00;
|
---|
| 226 | reader[ridx].prid[0][1]=0x00;
|
---|
| 227 | reader[ridx].prid[0][2]=parte_variable[73];
|
---|
| 228 | reader[ridx].prid[0][3]=parte_variable[74];
|
---|
| 229 | reader[ridx].caid[0] =(SYSTEM_NAGRA|parte_variable[76]);
|
---|
[1196] | 230 | memcpy(sk,&parte_variable[79],8);
|
---|
| 231 | memcpy(sk+8,&parte_variable[79],8);
|
---|
[1539] | 232 | cs_ri_log("type: NAGRA, caid: %04X, IRD ID: %s",reader[ridx].caid[0], cs_hexdump (1,irdId,4));
|
---|
| 233 | cs_ri_log("ProviderID: %s",cs_hexdump (1,reader[ridx].prid[0],4));
|
---|
[1196] | 234 |
|
---|
[1389] | 235 | memset(random, 0, 88);
|
---|
[1196] | 236 | memcpy(random, sk,16);
|
---|
| 237 | ReverseMem(random, 88);
|
---|
[1083] | 238 |
|
---|
| 239 |
|
---|
| 240 | BN_CTX *ctx3 = BN_CTX_new();
|
---|
| 241 | BIGNUM *bnN3 = BN_CTX_get(ctx3);
|
---|
| 242 | BIGNUM *bnE3 = BN_CTX_get(ctx3);
|
---|
| 243 | BIGNUM *bnCT3 = BN_CTX_get(ctx3);
|
---|
| 244 | BIGNUM *bnPT3 = BN_CTX_get(ctx3);
|
---|
| 245 | BN_bin2bn(d1_rsa_modulo, 88, bnN3);
|
---|
| 246 | BN_bin2bn(vFixed+4, 1, bnE3);
|
---|
| 247 | BN_bin2bn(random, 88, bnCT3);
|
---|
| 248 | BN_mod_exp(bnPT3, bnCT3, bnE3, bnN3, ctx3);
|
---|
| 249 | memset(d2_data, 0, 88);
|
---|
| 250 | BN_bn2bin(bnPT3, d2_data + (88-BN_num_bytes(bnPT3)));
|
---|
| 251 | BN_CTX_end(ctx3);
|
---|
| 252 | BN_CTX_free (ctx3);
|
---|
| 253 | ReverseMem(d2_data, 88);
|
---|
| 254 |
|
---|
[1043] | 255 | if(!do_cmd(0xd2,0x5a,0x52,0x03, d2_data))
|
---|
| 256 | {
|
---|
| 257 | cs_debug("[nagra-reader] CMD$D2 failed");
|
---|
[1389] | 258 | return ERROR;
|
---|
[1043] | 259 | }
|
---|
[1083] | 260 | if (cta_res[2] == 0x00)
|
---|
[1043] | 261 | {
|
---|
[1504] | 262 | memcpy(sessi,sk,16);
|
---|
[1083] | 263 | IDEA_KEY_SCHEDULE ks;
|
---|
[1504] | 264 | idea_set_encrypt_key(sessi,&ks);
|
---|
[1083] | 265 | idea_set_decrypt_key(&ks,&ksSession);
|
---|
[1539] | 266 | cs_debug("[nagra-reader] session key negotiated");
|
---|
[1389] | 267 | return OK;
|
---|
[1043] | 268 | }
|
---|
[1083] | 269 | cs_ri_log("Negotiate sessionkey was not successfull! Please check tivusat rsa key");
|
---|
[1389] | 270 | return ERROR;
|
---|
[1043] | 271 |
|
---|
| 272 | }
|
---|
| 273 |
|
---|
[1344] | 274 | static int NegotiateSessionKey(void)
|
---|
[598] | 275 | {
|
---|
| 276 | unsigned char cmd2b[] = {0x21, 0x40, 0x48, 0xA0, 0xCA, 0x00, 0x00, 0x43, 0x2B, 0x40, 0x1C, 0x54, 0xd1, 0x26, 0xe7, 0xe2, 0x40, 0x20, 0xd1, 0x66, 0xf4, 0x18, 0x97, 0x9d, 0x5f, 0x16, 0x8f, 0x7f, 0x7a, 0x55, 0x15, 0x82, 0x31, 0x14, 0x06, 0x57, 0x1a, 0x3f, 0xf0, 0x75, 0x62, 0x41, 0xc2, 0x84, 0xda, 0x4c, 0x2e, 0x84, 0xe9, 0x29, 0x13, 0x81, 0xee, 0xd6, 0xa9, 0xf5, 0xe9, 0xdb, 0xaf, 0x22, 0x51, 0x3d, 0x44, 0xb3, 0x20, 0x83, 0xde, 0xcb, 0x5f, 0x35, 0x2b, 0xb0, 0xce, 0x70, 0x02, 0x00};
|
---|
| 277 | unsigned char negot[64];
|
---|
| 278 | unsigned char tmp[64];
|
---|
| 279 | unsigned char idea1[16];
|
---|
| 280 | unsigned char idea2[16];
|
---|
| 281 | unsigned char sign1[8];
|
---|
| 282 | unsigned char sign2[8];
|
---|
[742] | 283 |
|
---|
[1504] | 284 | if (is_tiger)
|
---|
[598] | 285 | {
|
---|
[1043] | 286 | if (!NegotiateSessionKey_Tiger())
|
---|
[819] | 287 | {
|
---|
[1043] | 288 | cs_debug("[nagra-reader] NegotiateSessionKey_Tiger failed");
|
---|
[1389] | 289 | return ERROR;
|
---|
[819] | 290 | }
|
---|
[1389] | 291 | return OK;
|
---|
[598] | 292 | }
|
---|
[1504] | 293 | if (!has_dt08) // if we have no valid dt08 calc then we use rsa from config and hexserial for calc of sessionkey
|
---|
[1083] | 294 | {
|
---|
[1504] | 295 | memcpy(plainDT08RSA, reader[ridx].rsa_mod, 64);
|
---|
| 296 | memcpy(signature,reader[ridx].nagra_boxkey, 8);
|
---|
[1083] | 297 | }
|
---|
[1043] | 298 | if(!do_cmd(0x2a,0x02,0xaa,0x42,NULL))
|
---|
[819] | 299 | {
|
---|
[1043] | 300 | cs_debug("[nagra-reader] CMD$2A failed");
|
---|
[1389] | 301 | return ERROR;
|
---|
[819] | 302 | }
|
---|
[598] | 303 |
|
---|
[1043] | 304 | // RSA decrypt of cmd$2a data, result is stored in "negot"
|
---|
| 305 | ReverseMem(cta_res+2, 64);
|
---|
| 306 | unsigned char vFixed[] = {0,1,2,3};
|
---|
| 307 | BN_CTX *ctx = BN_CTX_new();
|
---|
| 308 | BIGNUM *bnN = BN_CTX_get(ctx);
|
---|
| 309 | BIGNUM *bnE = BN_CTX_get(ctx);
|
---|
| 310 | BIGNUM *bnCT = BN_CTX_get(ctx);
|
---|
| 311 | BIGNUM *bnPT = BN_CTX_get(ctx);
|
---|
[1504] | 312 | BN_bin2bn(plainDT08RSA, 64, bnN);
|
---|
[1043] | 313 | BN_bin2bn(vFixed+3, 1, bnE);
|
---|
| 314 | BN_bin2bn(cta_res+2, 64, bnCT);
|
---|
| 315 | BN_mod_exp(bnPT, bnCT, bnE, bnN, ctx);
|
---|
| 316 | memset(negot, 0, 64);
|
---|
| 317 | BN_bn2bin(bnPT, negot + (64-BN_num_bytes(bnPT)));
|
---|
| 318 |
|
---|
| 319 | memcpy(tmp, negot, 64);
|
---|
| 320 | ReverseMem(tmp, 64);
|
---|
| 321 |
|
---|
| 322 | // build sessionkey
|
---|
| 323 | // first halve is IDEA Hashed in chuncs of 8 bytes using the Signature1 from dt08 calc, CamID-Inv.CamID(16 bytes key) the results are the First 8 bytes of the Session key
|
---|
[1504] | 324 | memcpy(idea1, signature, 8);
|
---|
[1076] | 325 | memcpy(idea1+8, reader[ridx].hexserial+2, 4);
|
---|
| 326 | idea1[12] = ~reader[ridx].hexserial[2]; idea1[13] = ~reader[ridx].hexserial[3]; idea1[14] = ~reader[ridx].hexserial[4]; idea1[15] = ~reader[ridx].hexserial[5];
|
---|
[598] | 327 |
|
---|
[1043] | 328 | Signature(sign1, idea1, tmp, 32);
|
---|
| 329 | memcpy(idea2,sign1,8); memcpy(idea2+8,sign1,8);
|
---|
| 330 | Signature(sign2, idea2, tmp, 32);
|
---|
[1504] | 331 | memcpy(sessi,sign1,8); memcpy(sessi+8,sign2,8);
|
---|
[752] | 332 |
|
---|
[1043] | 333 | // prepare cmd$2b data
|
---|
| 334 | BN_bin2bn(negot, 64, bnCT);
|
---|
| 335 | BN_mod_exp(bnPT, bnCT, bnE, bnN, ctx);
|
---|
| 336 | memset(cmd2b+10, 0, 64);
|
---|
| 337 | BN_bn2bin(bnPT, cmd2b+10 + (64-BN_num_bytes(bnPT)));
|
---|
| 338 | BN_CTX_end(ctx);
|
---|
| 339 | BN_CTX_free (ctx);
|
---|
| 340 | ReverseMem(cmd2b+10, 64);
|
---|
[598] | 341 |
|
---|
[1043] | 342 | IDEA_KEY_SCHEDULE ks;
|
---|
[1504] | 343 | idea_set_encrypt_key(sessi,&ks);
|
---|
[1043] | 344 | idea_set_decrypt_key(&ks,&ksSession);
|
---|
[819] | 345 |
|
---|
[1043] | 346 | if(!do_cmd(0x2b,0x42,0xab,0x02, cmd2b+10))
|
---|
[819] | 347 | {
|
---|
[1043] | 348 | cs_debug("[nagra-reader] CMD$2B failed");
|
---|
[1389] | 349 | return ERROR;
|
---|
[598] | 350 | }
|
---|
[1043] | 351 |
|
---|
[1539] | 352 | cs_debug("[nagra-reader] session key negotiated");
|
---|
[819] | 353 |
|
---|
[1528] | 354 | DateTimeCMD();
|
---|
| 355 |
|
---|
[1043] | 356 | if (!CamStateRequest())
|
---|
[662] | 357 | {
|
---|
[1043] | 358 | cs_debug("[nagra-reader] CamStateRequest failed");
|
---|
[1389] | 359 | return ERROR;
|
---|
[662] | 360 | }
|
---|
[1528] | 361 | if RENEW_SESSIONKEY()
|
---|
[1043] | 362 | {
|
---|
| 363 | cs_ri_log("Negotiate sessionkey was not successfull! Please check rsa key and boxkey");
|
---|
[1389] | 364 | return ERROR;
|
---|
[1043] | 365 | }
|
---|
| 366 |
|
---|
[1389] | 367 | return OK;
|
---|
[598] | 368 | }
|
---|
| 369 |
|
---|
[1344] | 370 | static void decryptDT08(void)
|
---|
[598] | 371 | {
|
---|
| 372 |
|
---|
| 373 | unsigned char vFixed[] = {0,1,2,3};
|
---|
| 374 | unsigned char v[72];
|
---|
| 375 | unsigned char buf[72];
|
---|
| 376 | unsigned char sign2[8];
|
---|
[1162] | 377 | unsigned char static_dt08[73];
|
---|
| 378 | unsigned char camid[4];
|
---|
[598] | 379 | int i, n;
|
---|
| 380 | BN_CTX *ctx;
|
---|
| 381 | BIGNUM *bn_mod, *bn_exp, *bn_data, *bn_res;
|
---|
| 382 |
|
---|
| 383 | memcpy(static_dt08, &cta_res[12], 73);
|
---|
| 384 | // decrypt RSA Part of dt08
|
---|
| 385 | bn_mod = BN_new ();
|
---|
| 386 | bn_exp = BN_new ();
|
---|
| 387 | bn_data = BN_new ();
|
---|
| 388 | bn_res = BN_new ();
|
---|
| 389 | ctx= BN_CTX_new();
|
---|
| 390 | if (ctx == NULL) cs_debug("[nagra-reader] RSA Error in dt08 decrypt");
|
---|
| 391 | ReverseMem(static_dt08+1, 64);
|
---|
| 392 | BN_bin2bn (reader[ridx].rsa_mod, 64, bn_mod); // rsa modulus
|
---|
| 393 | BN_bin2bn (vFixed+3, 1, bn_exp); // exponent
|
---|
| 394 | BN_bin2bn (static_dt08+1, 64, bn_data);
|
---|
| 395 | BN_mod_exp (bn_res, bn_data, bn_exp, bn_mod, ctx);
|
---|
| 396 | memset (static_dt08+1, 0, 64);
|
---|
| 397 | n = BN_bn2bin (bn_res, static_dt08+1);
|
---|
[1162] | 398 | BN_CTX_free (ctx);
|
---|
[598] | 399 | ReverseMem(static_dt08+1, n);
|
---|
| 400 |
|
---|
| 401 | // RSA data can never be bigger than the modulo
|
---|
[679] | 402 | static_dt08[64] |= static_dt08[0] & 0x80;
|
---|
[598] | 403 |
|
---|
| 404 | // IdeaCamKey
|
---|
[1504] | 405 | memcpy (&IdeaCamKey[0], reader[ridx].nagra_boxkey, 8);
|
---|
| 406 | memcpy (&IdeaCamKey[8], irdId, 4);
|
---|
[598] | 407 | for (i = 0; i < 4; i++)
|
---|
[1504] | 408 | IdeaCamKey[12 + i] = ~irdId[i];
|
---|
[598] | 409 |
|
---|
| 410 | // now IDEA decrypt
|
---|
| 411 | IDEA_KEY_SCHEDULE ks;
|
---|
[1504] | 412 | idea_set_encrypt_key(IdeaCamKey,&ks);
|
---|
[598] | 413 | idea_set_decrypt_key(&ks,&ksSession);
|
---|
| 414 | memcpy (&buf[0], static_dt08+1, 64);
|
---|
| 415 | memcpy (&buf[64], static_dt08+65, 8);
|
---|
| 416 | memset(v,0,sizeof(v));
|
---|
| 417 | memset(static_dt08,0,sizeof(static_dt08));
|
---|
| 418 | idea_cbc_encrypt(buf,static_dt08,72,&ksSession,v,IDEA_DECRYPT);
|
---|
| 419 |
|
---|
[1504] | 420 | if (swapCW==1)
|
---|
[1162] | 421 | {
|
---|
| 422 | memset(camid,0xff,4);
|
---|
| 423 | }
|
---|
| 424 | else
|
---|
| 425 | {
|
---|
| 426 | memcpy(camid, reader[ridx].hexserial+2,4);
|
---|
| 427 | }
|
---|
| 428 | cs_debug("[nagra-reader] using camid %s for dt08 calc",cs_hexdump (1,camid,4));
|
---|
[718] | 429 |
|
---|
[598] | 430 | // Calculate signature
|
---|
[1504] | 431 | memcpy (signature, static_dt08, 8);
|
---|
[598] | 432 | memset (static_dt08 + 0, 0, 4);
|
---|
| 433 | memcpy (static_dt08 + 4, camid, 4);
|
---|
[1504] | 434 | Signature(sign2,IdeaCamKey,static_dt08,72);
|
---|
[598] | 435 |
|
---|
[1504] | 436 | if (memcmp (signature, sign2, 8)==0)
|
---|
[598] | 437 | {
|
---|
[1504] | 438 | has_dt08=1;
|
---|
| 439 | memcpy (plainDT08RSA, static_dt08+8, 64);
|
---|
[598] | 440 | cs_debug("[nagra-reader] DT08 signature check ok");
|
---|
| 441 | }
|
---|
| 442 | else
|
---|
| 443 | {
|
---|
[1504] | 444 | has_dt08=0;
|
---|
[598] | 445 | cs_debug("[nagra-reader] DT08 signature check nok");
|
---|
| 446 | }
|
---|
| 447 | }
|
---|
[662] | 448 |
|
---|
[1344] | 449 | static void addProvider()
|
---|
[598] | 450 | {
|
---|
[765] | 451 | int i;
|
---|
| 452 | int toadd=1;
|
---|
| 453 | for (i=0; i<reader[ridx].nprov; i++)
|
---|
[598] | 454 | {
|
---|
[765] | 455 | if ((cta_res[7]==reader[ridx].prid[i][2]) && (cta_res[8]==reader[ridx].prid[i][3]))
|
---|
| 456 | {
|
---|
| 457 | toadd = 0;
|
---|
[598] | 458 | }
|
---|
| 459 | }
|
---|
[765] | 460 | if (toadd)
|
---|
[598] | 461 | {
|
---|
[765] | 462 | reader[ridx].prid[reader[ridx].nprov][0]=0;
|
---|
| 463 | reader[ridx].prid[reader[ridx].nprov][1]=0;
|
---|
| 464 | reader[ridx].prid[reader[ridx].nprov][2]=cta_res[7];
|
---|
| 465 | reader[ridx].prid[reader[ridx].nprov][3]=cta_res[8];
|
---|
| 466 | memcpy(reader[ridx].sa[reader[ridx].nprov], reader[ridx].sa[0], 4);
|
---|
| 467 | reader[ridx].nprov+=1;
|
---|
[598] | 468 | }
|
---|
[765] | 469 | }
|
---|
[798] | 470 |
|
---|
[1344] | 471 | static int ParseDataType(unsigned char dt)
|
---|
[598] | 472 | {
|
---|
[798] | 473 | char ds[16], de[16];
|
---|
| 474 | ushort chid;
|
---|
[598] | 475 | switch(dt)
|
---|
| 476 | {
|
---|
| 477 | case IRDINFO:
|
---|
| 478 | {
|
---|
[1083] | 479 | reader[ridx].prid[0][0]=0;
|
---|
| 480 | reader[ridx].prid[0][1]=0;
|
---|
| 481 | reader[ridx].prid[0][2]=cta_res[7];
|
---|
| 482 | reader[ridx].prid[0][3]=cta_res[8];
|
---|
[1167] | 483 | if ( ((cta_res[7] == 0x34) && (cta_res[8] == 0x11)) || ((cta_res[7] == 0x04) && (cta_res[8] == 0x01))) //provider 3411, 0401 needs cw swap
|
---|
[1162] | 484 | {
|
---|
[1167] | 485 | cs_debug("[nagra-reader] detect provider with swap cw!");
|
---|
[1504] | 486 | swapCW=1;
|
---|
[1162] | 487 | }
|
---|
| 488 |
|
---|
[1083] | 489 | reader[ridx].prid[1][0]=0x00;
|
---|
| 490 | reader[ridx].prid[1][1]=0x00;
|
---|
| 491 | reader[ridx].prid[1][2]=0x00;
|
---|
| 492 | reader[ridx].prid[1][3]=0x00;
|
---|
| 493 | memcpy(reader[ridx].sa[1], reader[ridx].sa[0], 4);
|
---|
| 494 | reader[ridx].nprov+=1;
|
---|
[1162] | 495 |
|
---|
[720] | 496 | reader[ridx].caid[0] =(SYSTEM_NAGRA|cta_res[11]);
|
---|
[1504] | 497 | memcpy(irdId,cta_res+14,4);
|
---|
| 498 | cs_debug("[nagra-reader] type: NAGRA, caid: %04X, IRD ID: %s",reader[ridx].caid[0], cs_hexdump (1,irdId,4));
|
---|
| 499 | cs_debug("[nagra-reader] ProviderID: %s",cs_hexdump (1,reader[ridx].prid[0],4));
|
---|
| 500 | return OK;
|
---|
[598] | 501 | }
|
---|
| 502 | case TIERS:
|
---|
[798] | 503 | if ((cta_lr>33) && (chid=b2i(2, cta_res+11)))
|
---|
| 504 | {
|
---|
| 505 | int id=(cta_res[7]*256)|cta_res[8];
|
---|
| 506 | tier_date(b2i(2, cta_res+20)-0x7f7, ds, 15);
|
---|
| 507 | tier_date(b2i(2, cta_res+13)-0x7f7, de, 15);
|
---|
| 508 | cs_ri_log("|%04X|%04X |%s |%s |", id,chid, ds, de);
|
---|
[1125] | 509 | addProvider();
|
---|
[798] | 510 | }
|
---|
[598] | 511 | case 0x08:
|
---|
[726] | 512 | case 0x88: if (cta_res[11] == 0x49) decryptDT08();
|
---|
[598] | 513 | default:
|
---|
[1389] | 514 | return OK;
|
---|
[598] | 515 | }
|
---|
[1389] | 516 | return ERROR;
|
---|
[598] | 517 | }
|
---|
| 518 |
|
---|
[1344] | 519 | static int GetDataType(unsigned char dt, int len, int shots)
|
---|
[598] | 520 | {
|
---|
| 521 | int i;
|
---|
| 522 | for(i=0; i<shots; i++)
|
---|
| 523 | {
|
---|
| 524 | if(!do_cmd(0x22,0x03,0xA2,len,&dt))
|
---|
| 525 | {
|
---|
| 526 | cs_debug("[nagra-reader] failed to get datatype %02X",dt);
|
---|
[1389] | 527 | return ERROR;
|
---|
[598] | 528 | }
|
---|
[1389] | 529 | if((cta_res[2]==0) && (dt != 0x08 || dt != 0x88)) return OK;
|
---|
| 530 | if(!ParseDataType(dt&0x0F)) return ERROR;
|
---|
| 531 | if ((dt != 0x08 || dt != 0x88) && (cta_res[11] == 0x49)) return OK; //got dt08 data
|
---|
[598] | 532 | dt|=0x80; // get next item
|
---|
| 533 | }
|
---|
[1389] | 534 | return OK;
|
---|
[598] | 535 | }
|
---|
| 536 |
|
---|
[1389] | 537 | int nagra2_card_init(ATR newatr)
|
---|
[598] | 538 | {
|
---|
[1389] | 539 | get_atr;
|
---|
[1504] | 540 | memset(rom, 0, 15);
|
---|
[598] | 541 | reader[ridx].nprov = 1;
|
---|
[1076] | 542 | memset(reader[ridx].hexserial, 0, 8);
|
---|
[598] | 543 | reader[ridx].caid[0]=SYSTEM_NAGRA;
|
---|
| 544 |
|
---|
[819] | 545 | if (memcmp(atr+11, "DNASP", 5)==0)
|
---|
[598] | 546 | {
|
---|
[1399] | 547 | cs_ri_log("detect native NAGRA card T1 protocol");
|
---|
[1504] | 548 | memcpy(rom,atr+11,15);
|
---|
[598] | 549 | }
|
---|
[1083] | 550 | else if (memcmp(atr+11, "TIGER", 5)==0 || (memcmp(atr+11, "NCMED", 5)==0))
|
---|
[819] | 551 | {
|
---|
[1399] | 552 | cs_ri_log("detect NAGRA tiger card");
|
---|
[1504] | 553 | memcpy(rom,atr+11,15);
|
---|
| 554 | is_tiger=1;
|
---|
[819] | 555 | }
|
---|
[1200] | 556 | else if ((!memcmp(atr+4, "IRDETO", 6)) && ((atr[14]==0x03) && (atr[15]==0x84) && (atr[16]==0x55)))
|
---|
[598] | 557 | {
|
---|
[1399] | 558 | cs_ri_log("detect Irdeto tunneled NAGRA card");
|
---|
[1381] | 559 | if(!reader[ridx].has_rsa)
|
---|
| 560 | {
|
---|
[1399] | 561 | cs_ri_log("switching back to Irdeto mode");
|
---|
[1389] | 562 | return ERROR;
|
---|
[1381] | 563 | }
|
---|
[1399] | 564 | cs_ri_log("using NAGRA mode");
|
---|
[1504] | 565 | is_pure_nagra=1;
|
---|
[598] | 566 | if(!do_cmd(0x10,0x02,0x90,0x11,0))
|
---|
| 567 | {
|
---|
| 568 | cs_debug("[nagra-reader] get rom version failed");
|
---|
[1389] | 569 | return ERROR;
|
---|
[598] | 570 | }
|
---|
[1504] | 571 | memcpy(rom,cta_res+2,15);
|
---|
[598] | 572 | }
|
---|
[1389] | 573 | else return ERROR;
|
---|
[819] | 574 |
|
---|
[1504] | 575 | if (!is_tiger)
|
---|
[598] | 576 | {
|
---|
[798] | 577 | CamStateRequest();
|
---|
[819] | 578 | if(!do_cmd(0x12,0x02,0x92,0x06,0))
|
---|
| 579 | {
|
---|
| 580 | cs_debug("[nagra-reader] get Serial failed");
|
---|
[1389] | 581 | return ERROR;
|
---|
[819] | 582 | }
|
---|
[1076] | 583 | memcpy(reader[ridx].hexserial+2, cta_res+2, 4);
|
---|
[1116] | 584 | cs_debug("[nagra-reader] SER: %s", cs_hexdump (1, reader[ridx].hexserial+2, 4));
|
---|
[1165] | 585 | memcpy(reader[ridx].sa[0], cta_res+2, 2);
|
---|
[819] | 586 |
|
---|
[1389] | 587 | if(!GetDataType(DT01,0x0E,MAX_REC)) return ERROR;
|
---|
[819] | 588 | cs_debug("[nagra-reader] DT01 DONE");
|
---|
| 589 | CamStateRequest();
|
---|
[1389] | 590 | if(!GetDataType(IRDINFO,0x39,MAX_REC)) return ERROR;
|
---|
[819] | 591 | cs_debug("[nagra-reader] IRDINFO DONE");
|
---|
| 592 | CamStateRequest();
|
---|
[1389] | 593 | if(!GetDataType(CAMDATA,0x55,10)) return ERROR;
|
---|
[819] | 594 | cs_debug("[nagra-reader] CAMDATA Done");
|
---|
[1389] | 595 | if(!GetDataType(0x04,0x44,MAX_REC)) return ERROR;
|
---|
[819] | 596 | cs_debug("[nagra-reader] DT04 DONE");
|
---|
| 597 | CamStateRequest();
|
---|
| 598 |
|
---|
[1504] | 599 | if (!memcmp(rom+5, "181", 3)==0) //dt05 is not supported by rom181
|
---|
[819] | 600 | {
|
---|
| 601 | cs_ri_log("-----------------------------------------");
|
---|
| 602 | cs_ri_log("|id |tier |valid from |valid to |");
|
---|
| 603 | cs_ri_log("+----+--------+------------+------------+");
|
---|
[1389] | 604 | if(!GetDataType(TIERS,0x57,MAX_REC)) return ERROR;
|
---|
[819] | 605 | cs_ri_log("-----------------------------------------");
|
---|
| 606 | CamStateRequest();
|
---|
| 607 | }
|
---|
| 608 |
|
---|
[1389] | 609 | if(!GetDataType(DT06,0x16,MAX_REC)) return ERROR;
|
---|
[819] | 610 | cs_debug("[nagra-reader] DT06 DONE");
|
---|
| 611 | CamStateRequest();
|
---|
[797] | 612 | }
|
---|
[598] | 613 | if (!NegotiateSessionKey())
|
---|
| 614 | {
|
---|
| 615 | cs_debug("[nagra-reader] NegotiateSessionKey failed");
|
---|
[1389] | 616 | return ERROR;
|
---|
[598] | 617 | }
|
---|
[1504] | 618 | if ((reader[ridx].cardmhz != 368) && (is_pure_nagra==0))
|
---|
[1399] | 619 | cs_log("WARNING: For NAGRA2 cards you will have to set 'cardmhz = 368' in oscam.server");
|
---|
[819] | 620 |
|
---|
[1389] | 621 | return OK;
|
---|
[598] | 622 | }
|
---|
| 623 |
|
---|
| 624 | int nagra2_card_info(void)
|
---|
| 625 | {
|
---|
[765] | 626 | int i;
|
---|
[1504] | 627 | cs_ri_log("ROM: %c %c %c %c %c %c %c %c", rom[0], rom[1], rom[2],rom[3], rom[4], rom[5], rom[6], rom[7]);
|
---|
| 628 | cs_ri_log("REV: %c %c %c %c %c %c", rom[9], rom[10], rom[11], rom[12], rom[13], rom[14]);
|
---|
[1083] | 629 | cs_ri_log("SER: %s", cs_hexdump (1, reader[ridx].hexserial+2, 4));
|
---|
[765] | 630 | cs_ri_log("CAID: %04X",reader[ridx].caid[0]);
|
---|
| 631 | cs_ri_log("Prv.ID: %s(sysid)",cs_hexdump (1,reader[ridx].prid[0],4));
|
---|
| 632 | for (i=1; i<reader[ridx].nprov; i++)
|
---|
| 633 | {
|
---|
| 634 | cs_ri_log("Prv.ID: %s",cs_hexdump (1,reader[ridx].prid[i],4));
|
---|
| 635 | }
|
---|
[1381] | 636 | cs_log("[nagra-reader] ready for requests");
|
---|
[1389] | 637 | return OK;
|
---|
[598] | 638 | }
|
---|
| 639 |
|
---|
[800] | 640 | void nagra2_post_process(void)
|
---|
[739] | 641 | {
|
---|
[1504] | 642 | if (!is_tiger)
|
---|
[1076] | 643 | {
|
---|
| 644 | CamStateRequest();
|
---|
[1528] | 645 | if RENEW_SESSIONKEY() NegotiateSessionKey();
|
---|
| 646 | if SENDDATETIME() DateTimeCMD();
|
---|
[1076] | 647 | }
|
---|
[739] | 648 | }
|
---|
| 649 |
|
---|
[598] | 650 | int nagra2_do_ecm(ECM_REQUEST *er)
|
---|
| 651 | {
|
---|
[1504] | 652 | if (!is_tiger)
|
---|
[598] | 653 | {
|
---|
[819] | 654 | int retry=0;
|
---|
| 655 | if(!do_cmd(er->ecm[3],er->ecm[4]+2,0x87,0x02, er->ecm+3+2))
|
---|
[701] | 656 | {
|
---|
[819] | 657 | cs_debug("[nagra-reader] nagra2_do_ecm failed, retry");
|
---|
[1381] | 658 | cs_sleepms(10);
|
---|
[819] | 659 | if(!do_cmd(er->ecm[3],er->ecm[4]+2,0x87,0x02, er->ecm+3+2))
|
---|
| 660 | {
|
---|
[1381] | 661 | cs_debug("[nagra-reader] nagra2_do_ecm failed, retry failed!");
|
---|
[1389] | 662 | return ERROR;
|
---|
[819] | 663 | }
|
---|
| 664 |
|
---|
[701] | 665 | }
|
---|
[1539] | 666 | cs_sleepms(10);
|
---|
[1333] | 667 | while(!CamStateRequest() && retry < 3)
|
---|
[819] | 668 | {
|
---|
[1076] | 669 | cs_debug("[nagra-reader] CamStateRequest failed, try: %d", retry);
|
---|
[1259] | 670 | retry++;
|
---|
[1333] | 671 | cs_sleepms(10);
|
---|
[819] | 672 | }
|
---|
[1528] | 673 | if (HAS_CW() && (do_cmd(0x1C,0x02,0x9C,0x36,NULL)))
|
---|
[819] | 674 | {
|
---|
| 675 | unsigned char v[8];
|
---|
| 676 | memset(v,0,sizeof(v));
|
---|
| 677 | idea_cbc_encrypt(&cta_res[30],er->cw,8,&ksSession,v,IDEA_DECRYPT);
|
---|
| 678 | memset(v,0,sizeof(v));
|
---|
| 679 | idea_cbc_encrypt(&cta_res[4],er->cw+8,8,&ksSession,v,IDEA_DECRYPT);
|
---|
[1504] | 680 | if (swapCW==1)
|
---|
[819] | 681 | {
|
---|
[1381] | 682 | cs_debug("[nagra-reader] swap cws");
|
---|
[819] | 683 | unsigned char tt[8];
|
---|
| 684 | memcpy(&tt[0],&er->cw[0],8);
|
---|
| 685 | memcpy(&er->cw[0],&er->cw[8],8);
|
---|
| 686 | memcpy(&er->cw[8],&tt[0],8);
|
---|
| 687 | }
|
---|
[1389] | 688 | return OK;
|
---|
[819] | 689 | }
|
---|
[598] | 690 | }
|
---|
[819] | 691 | else
|
---|
[752] | 692 | {
|
---|
[1259] | 693 | //check ECM prov id
|
---|
| 694 | if (memcmp(&reader[ridx].prid[0][2], er->ecm+5, 2))
|
---|
[1389] | 695 | return ERROR;
|
---|
[1259] | 696 |
|
---|
| 697 | // ecm_data: 80 30 89 D3 87 54 11 10 DA A6 0F 4B 92 05 34 00 ...
|
---|
[1076] | 698 | //serial_data: A0 CA 00 00 8C D3 8A 00 00 00 00 00 10 DA A6 0F .
|
---|
| 699 | unsigned char ecm_trim[150];
|
---|
| 700 | memset(ecm_trim, 0, 150);
|
---|
| 701 | memcpy(&ecm_trim[5], er->ecm+3+2+2, er->ecm[4]+2);
|
---|
| 702 | if(do_cmd(er->ecm[3],er->ecm[4]+5,0x53,0x16, ecm_trim))
|
---|
[819] | 703 | {
|
---|
[1043] | 704 | if(cta_res[2] == 0x01)
|
---|
| 705 | {
|
---|
[1076] | 706 |
|
---|
[1043] | 707 | unsigned char v[8];
|
---|
| 708 | memset(v,0,sizeof(v));
|
---|
| 709 | idea_cbc_encrypt(&cta_res[14],er->cw,8,&ksSession,v,IDEA_DECRYPT);
|
---|
| 710 | memset(v,0,sizeof(v));
|
---|
| 711 | idea_cbc_encrypt(&cta_res[6],er->cw+8,8,&ksSession,v,IDEA_DECRYPT);
|
---|
[1389] | 712 | return OK;
|
---|
[1043] | 713 | }
|
---|
| 714 | cs_debug("[nagra-reader] can't decode ecm");
|
---|
[1389] | 715 | return ERROR;
|
---|
[819] | 716 | }
|
---|
[752] | 717 | }
|
---|
[1389] | 718 | return ERROR;
|
---|
[598] | 719 | }
|
---|
[739] | 720 |
|
---|
[1766] | 721 | int nagra2_get_emm_type(EMM_PACKET *ep) //returns TRUE if shared emm matches SA, unique emm matches serial, or global or unknown
|
---|
| 722 | {
|
---|
| 723 | switch (ep->emm[0]) {
|
---|
| 724 | case 0x83:
|
---|
| 725 | memset(ep->hexserial,0,8);
|
---|
| 726 | ep->hexserial[0] = ep->emm[5];
|
---|
| 727 | ep->hexserial[1] = ep->emm[4];
|
---|
| 728 | ep->hexserial[2] = ep->emm[3];
|
---|
| 729 | ep->hexserial[3] = ep->emm[6];
|
---|
| 730 | if (ep->emm[7] == 0x10)
|
---|
| 731 | ep->type = SHARED;
|
---|
| 732 | else
|
---|
| 733 | ep->type = UNIQUE;
|
---|
| 734 | return (!memcmp (reader[ridx].hexserial, ep->hexserial, 4));
|
---|
| 735 | case 0x82:
|
---|
| 736 | ep->type = GLOBAL;
|
---|
| 737 | return TRUE;
|
---|
| 738 | default:
|
---|
| 739 | ep->type = UNKNOWN;
|
---|
| 740 | return TRUE;
|
---|
| 741 | }
|
---|
| 742 | }
|
---|
| 743 |
|
---|
[662] | 744 | int nagra2_do_emm(EMM_PACKET *ep)
|
---|
| 745 | {
|
---|
[1504] | 746 | if (!is_tiger)
|
---|
[662] | 747 | {
|
---|
[1259] | 748 | if(!do_cmd(ep->emm[8],ep->emm[9]+2,0x84,0x02,ep->emm+8+2))
|
---|
| 749 | {
|
---|
| 750 | cs_debug("[nagra-reader] nagra2_do_emm failed");
|
---|
[1389] | 751 | return ERROR;
|
---|
[1259] | 752 | }
|
---|
[1381] | 753 | // for slow t14 nagra cards, we must do additional timeout
|
---|
[1504] | 754 | if (is_pure_nagra==1)
|
---|
[1333] | 755 | {
|
---|
[1381] | 756 | cs_sleepms(300);
|
---|
[1333] | 757 | }
|
---|
| 758 | cs_sleepms(250);
|
---|
[1259] | 759 | nagra2_post_process();
|
---|
[662] | 760 | }
|
---|
[1259] | 761 | else
|
---|
| 762 | {
|
---|
| 763 | //check EMM prov id
|
---|
| 764 | if (memcmp(&reader[ridx].prid[0][2], ep->emm+10, 2))
|
---|
[1389] | 765 | return ERROR;
|
---|
[1259] | 766 |
|
---|
| 767 | // emm_data: 82 70 8E 00 00 00 00 00 D3 87 8D 11 C0 F4 B1 27 2C 3D 25 94 ...
|
---|
| 768 | //serial_data: A0 CA 00 00 8C D3 8A 01 00 00 00 00 C0 F4 B1 27 2C 3D 25 94 ...
|
---|
| 769 | unsigned char emm_trim[150];
|
---|
| 770 | memset(emm_trim, 0, 150);
|
---|
| 771 | memcpy(&emm_trim[5], ep->emm+3+5+2+2, ep->emm[9]+2);
|
---|
| 772 | if(!do_cmd(ep->emm[8],ep->emm[9]+5,0x53,0x16, emm_trim))
|
---|
| 773 | {
|
---|
| 774 | cs_debug("[nagra-reader] nagra2_do_emm failed");
|
---|
[1389] | 775 | return ERROR;
|
---|
[1259] | 776 | }
|
---|
| 777 | cs_sleepms(300);
|
---|
| 778 | }
|
---|
[1389] | 779 | return OK;
|
---|
[662] | 780 | }
|
---|