source: titan/titan/cacc.h @ 45594

Last change on this file since 45594 was 45594, checked in by obi, 8 months ago

test add openssl ifdef to cacc

  • Property svn:executable set to *
File size: 50.0 KB
Line 
1#ifndef CACC_H
2#define CACC_H
3
4#define xx_debug    0
5#define yy_debug    0
6
7#ifdef QUIET
8char authie[7];
9char devie[7];
10#endif
11
12static uint8_t NullPMT[50]={0x9F,0x80,0x32,0x2E,0x03,0x6E,0xA7,0x37,0x00,0x00,0x1B,0x15,0x7D,0x00,0x00,0x03,0x15,0x7E,0x00,0x00,0x03,0x15,0x7F,0x00,0x00,0x06,0x15,0x80,0x00,0x00,0x06,0x15,0x82,0x00,0x00,0x0B,0x08,0x7B,0x00,0x00,0x05,0x09,0x42,0x00,0x00,0x06,0x15,0x81,0x00,0x00};
13#ifdef MIPSEL
14static const char *descrambler_filename = "/dev/dvb/adapter0/ca0";
15#else
16static const char *descrambler_filename = "/dev/dvb/adapter0/ca3";
17#endif
18static int desc_fd = -1;
19static int desc_user_count = 0;
20
21static int testwork = 0;
22
23unsigned char dh_p[256] = {       /* prime */
24        0xd6, 0x27, 0x14, 0x7a, 0x7c, 0x0c, 0x26, 0x63, 0x9d, 0x82, 0xeb, 0x1f, 0x4a, 0x18, 0xff, 0x6c,
25        0x34, 0xad, 0xea, 0xa6, 0xc0, 0x23, 0xe6, 0x65, 0xfc, 0x8e, 0x32, 0xc3, 0x33, 0xf4, 0x91, 0xa7,
26        0xcc, 0x88, 0x58, 0xd7, 0xf3, 0xb3, 0x17, 0x5e, 0xb0, 0xa8, 0xeb, 0x5c, 0xd4, 0xd8, 0x3a, 0xae,
27        0x8e, 0x75, 0xa1, 0x50, 0x5f, 0x5d, 0x67, 0xc5, 0x40, 0xf4, 0xb3, 0x68, 0x35, 0xd1, 0x3a, 0x4c,
28        0x93, 0x7f, 0xca, 0xce, 0xdd, 0x83, 0x29, 0x01, 0xc8, 0x4b, 0x76, 0x81, 0x56, 0x34, 0x83, 0x31,
29        0x92, 0x72, 0x65, 0x7b, 0xac, 0xd9, 0xda, 0xa9, 0xd1, 0xd3, 0xe5, 0x77, 0x58, 0x6f, 0x5b, 0x44,
30        0x3e, 0xaf, 0x7f, 0x6d, 0xf5, 0xcf, 0x0a, 0x80, 0x0d, 0xa5, 0x56, 0x4f, 0x4b, 0x85, 0x41, 0x0f,
31        0x13, 0x41, 0x06, 0x1f, 0xf3, 0xd9, 0x65, 0x36, 0xae, 0x47, 0x41, 0x1f, 0x1f, 0xe0, 0xde, 0x69,
32        0xe5, 0x86, 0x2a, 0xa1, 0xf2, 0x48, 0x02, 0x92, 0x68, 0xa6, 0x37, 0x9f, 0x76, 0x4f, 0x7d, 0x94,
33        0x5d, 0x10, 0xe5, 0xab, 0x5d, 0xb2, 0xf3, 0x12, 0x8c, 0x79, 0x03, 0x92, 0xa6, 0x7f, 0x8a, 0x78,
34        0xb0, 0xba, 0xc5, 0xb5, 0x31, 0xc5, 0xc8, 0x22, 0x6e, 0x29, 0x02, 0x40, 0xab, 0xe7, 0x5c, 0x23,
35        0x33, 0x7f, 0xcb, 0x86, 0xc7, 0xb4, 0xfd, 0xaa, 0x44, 0xcd, 0x9c, 0x9f, 0xba, 0xac, 0x3a, 0xcf,
36        0x7e, 0x31, 0x5f, 0xa8, 0x47, 0xce, 0xca, 0x1c, 0xb4, 0x77, 0xa0, 0xec, 0x9a, 0x46, 0xd4, 0x79,
37        0x7b, 0x64, 0xbb, 0x6c, 0x91, 0xb2, 0x38, 0x01, 0x65, 0x11, 0x45, 0x9f, 0x62, 0x08, 0x6f, 0x31,
38        0xcf, 0xc4, 0xba, 0xdc, 0xd0, 0x03, 0x91, 0xf1, 0x18, 0x1f, 0xcb, 0x4d, 0xfc, 0x73, 0x5a, 0xa2,
39        0x15, 0xb8, 0x3c, 0x8d, 0x80, 0x92, 0x1c, 0xa1, 0x03, 0xd0, 0x83, 0x2f, 0x5f, 0xe3, 0x07, 0x69
40};
41
42unsigned char dh_g[256] = {       /* generator */
43        0x95, 0x7d, 0xd1, 0x49, 0x68, 0xc1, 0xa5, 0xf1, 0x48, 0xe6, 0x50, 0x4f, 0xa1, 0x10, 0x72, 0xc4,
44        0xef, 0x12, 0xec, 0x2d, 0x94, 0xbe, 0xc7, 0x20, 0x2c, 0x94, 0xf9, 0x68, 0x67, 0x0e, 0x22, 0x17,
45        0xb5, 0x5c, 0x0b, 0xca, 0xac, 0x9f, 0x25, 0x9c, 0xd2, 0xa6, 0x1a, 0x20, 0x10, 0x16, 0x6a, 0x42,
46        0x27, 0x83, 0x47, 0x42, 0xa0, 0x07, 0x52, 0x09, 0x33, 0x97, 0x4e, 0x30, 0x57, 0xd8, 0xb7, 0x1e,
47        0x46, 0xa6, 0xba, 0x4e, 0x40, 0x6a, 0xe9, 0x1a, 0x5a, 0xa0, 0x74, 0x56, 0x92, 0x55, 0xc2, 0xbd,
48        0x44, 0xcd, 0xb3, 0x33, 0xf7, 0x35, 0x46, 0x25, 0xdf, 0x84, 0x19, 0xf3, 0xe2, 0x7a, 0xac, 0x4e,
49        0xee, 0x1a, 0x86, 0x3b, 0xb3, 0x87, 0xa6, 0x66, 0xc1, 0x70, 0x21, 0x41, 0xd3, 0x58, 0x36, 0xb5,
50        0x3b, 0x6e, 0xa1, 0x55, 0x60, 0x9a, 0x59, 0xd3, 0x85, 0xd8, 0xdc, 0x6a, 0xff, 0x41, 0xb6, 0xbf,
51        0x42, 0xde, 0x64, 0x00, 0xd0, 0xee, 0x3a, 0xa1, 0x8a, 0xed, 0x12, 0xf9, 0xba, 0x54, 0x5c, 0xdb,
52        0x06, 0x24, 0x49, 0xe8, 0x47, 0xcf, 0x5b, 0xe4, 0xbb, 0xc0, 0xaa, 0x8a, 0x8c, 0xbe, 0x73, 0xd9,
53        0x02, 0xea, 0xee, 0x8d, 0x87, 0x5b, 0xbf, 0x78, 0x04, 0x41, 0x9e, 0xa8, 0x5c, 0x3c, 0x49, 0xde,
54        0x88, 0x6d, 0x62, 0x21, 0x7f, 0xf0, 0x5e, 0x2d, 0x1d, 0xfc, 0x47, 0x0d, 0x1b, 0xaa, 0x4e, 0x0d,
55        0x78, 0x20, 0xfe, 0x57, 0x0f, 0xca, 0xdf, 0xeb, 0x3c, 0x84, 0xa7, 0xe1, 0x61, 0xb2, 0x95, 0x98,
56        0x07, 0x73, 0x8e, 0x51, 0xc6, 0x87, 0xe4, 0xcf, 0xf1, 0x5f, 0x86, 0x99, 0xec, 0x8d, 0x44, 0x92,
57        0x2c, 0x99, 0xf6, 0xc0, 0xf4, 0x39, 0xe8, 0x05, 0xbf, 0xc1, 0x56, 0xde, 0xfe, 0x93, 0x75, 0x06,
58        0x69, 0x87, 0x83, 0x06, 0x51, 0x80, 0xa5, 0x6e, 0xa6, 0x19, 0x7d, 0x3b, 0xef, 0xfb, 0xe0, 0x4a
59};
60
61/* Byte 0 to 15 are AES Key, Byte 16 to 31 are IV */
62
63int descrambler_set_key(struct dvbdev* node, int index, int parity, unsigned char *data)
64{
65        debug(620, "start");
66        if(node == NULL)
67        {
68                err("NULL detect");
69                return 1;
70        }
71       
72        int rc = 0;
73        struct ca_descr_data d;
74
75#ifdef MIPSEL
76        if(desc_fd == -1)
77                descrambler_open();
78        if (desc_fd > 0)
79        {
80                d.index = index;
81                d.parity = parity;
82                d.data_type = CA_DATA_KEY;
83                d.length = 16;
84                d.data = data;
85
86                printf("[titan] DESCR_DATA: -> ");
87                hexdump(data, 32);
88
89                if(checkbox("DM900") == 1 || checkbox("DM920") == 1 || checkbox("DM520") == 1 || checkbox("DM525") == 1 || checkbox("DM7020HD") == 1 || checkbox("DM7020HDV2") == 1 || checkchipset("BCM7424") == 1)
90                        rc = ioctl(desc_fd, CA_SET_DESCR_DATA_DREAM, &d);
91                else
92                        rc = ioctl(desc_fd, CA_SET_DESCR_DATA, &d);
93               
94                if (rc)
95                        printf("[titan] #### ERROR: CA_DATA_KEY - CA_SET_DESCR_DATA index=0x%04x parity=0x%04x (errno=%d %s)\n", index, parity, errno, strerror(errno));
96                else
97                        printf("[titan] #### CA_DATA_KEY - CA_SET_DESCR_DATA index=0x%04x parity=0x%04x\n", index, parity);
98               
99                d.index = index;
100                d.parity = parity;
101                d.data_type = CA_DATA_IV;
102                d.length = 16;
103                d.data = data + 16;
104
105                if(checkbox("DM900") == 1 || checkbox("DM920") == 1 || checkbox("DM520") == 1 || checkbox("DM525") == 1 || checkbox("DM7020HD") == 1 || checkbox("DM7020HDV2") == 1)
106                        rc = ioctl(desc_fd, CA_SET_DESCR_DATA_DREAM, &d);
107                else
108                        rc = ioctl(desc_fd, CA_SET_DESCR_DATA, &d);
109               
110                if (rc)
111                        printf("[titan] #### ERROR: CA_DATA_IV - CA_SET_DESCR_DATA index=0x%04x parity=0x%04x (errno=%d %s)\n", index, parity, errno, strerror(errno));
112                else
113                        printf("[titan] #### CA_DATA_IV - CA_SET_DESCR_DATA index=0x%04x parity=0x%04x\n", index, parity);     
114                ciplusrun = 1;
115        }
116        /*if(testwork == 0)
117        {
118                if(checkbox("DM900") == 1)
119                                descrambler_deinit();
120        }
121        else
122                testwork = 0;*/
123        //descrambler_close();
124
125#else
126       
127        index |= 0x100;
128       
129        if(desc_fd == -1)
130                descrambler_open();
131        if (desc_fd > 0)
132        {
133                d.index = index;
134                d.parity = parity;
135                d.data_type = CA_DATA_KEY;
136                d.length = 32;
137                d.data = data;
138
139                printf("[titan] Index: %d Parity: (%d) -> ", d.index, d.parity);
140                hexdump(d.data, 32);
141               
142                //if (ioctl(desc_fd, CA_SET_DESCR_DATA, &d))
143                rc = ioctl(desc_fd, CA_SET_DESCR_DATA, &d);
144                if (rc)
145                        printf("###############\nERROR - CA_SET_DESCR_DATA -> CA_DATA_KEY\n###############\n");
146                else
147                        printf("###############\nCA_SET_DESCR_DATA -> CA_DATA_KEY RCode: %i\n###############\n", rc);
148
149        }
150        descrambler_close();
151#endif
152
153        return 0;
154}
155
156void resendKey(struct dvbdev* dvbnode)
157{
158        debug(620, "resendKey");
159//      if (!tslot->SidBlackListed && (tslot->inUse || tslot->slot == cCA::GetInstance()->GetLiveSlot()))
160//              descrambler_set_key((int)tslot->source, tslot->lastParity, tslot->lastKey);
161//      if (!dvbnode->caslot->sidblacklisted && (dvbnode->caslot->inuse || dvbnode->caslot->slot == cCA::GetInstance()->GetLiveSlot()))
162//              descrambler_set_key((int)dvbnode->caslot->source, dvbnode->caslot->lastParity, dvbnode->caslot->lastKey);
163
164        struct cc_ctrl_data *cc_data = (struct cc_ctrl_data*)(dvbnode->caslot->private_data);
165        descrambler_set_key(dvbnode, 0, cc_data->slot->lastParity, cc_data->slot->lastKey);
166}
167
168int aes_xcbc_mac_init(struct aes_xcbc_mac_ctx *ctx, const uint8_t *key)
169{
170        debug(620, "start");
171        AES_KEY aes_key;
172        int y, x;
173
174        AES_set_encrypt_key(key, 128, &aes_key);
175
176        for (y = 0; y < 3; y++) {
177                for (x = 0; x < 16; x++)
178                        ctx->K[y][x] = y + 1;
179                AES_ecb_encrypt(ctx->K[y], ctx->K[y], &aes_key, 1);
180        }
181
182        /* setup K1 */
183        AES_set_encrypt_key(ctx->K[0], 128, &ctx->key);
184
185        memset(ctx->IV, 0, 16);
186        ctx->buflen = 0;
187
188        return 0;
189}
190
191int aes_xcbc_mac_process(struct aes_xcbc_mac_ctx *ctx, const uint8_t *in, unsigned int len)
192{
193        debug(620, "start");
194        while (len) {
195                if (ctx->buflen == 16) {
196                        AES_ecb_encrypt(ctx->IV, ctx->IV, &ctx->key, 1);
197                        ctx->buflen = 0;
198                }
199                ctx->IV[ctx->buflen++] ^= *in++;
200                --len;
201        }
202
203        return 0;
204}
205
206int aes_xcbc_mac_done(struct aes_xcbc_mac_ctx *ctx, uint8_t *out)
207{
208        debug(620, "start");
209        int i;
210
211        if (ctx->buflen == 16) {
212                /* K2 */
213                for (i = 0; i < 16; i++)
214                        ctx->IV[i] ^= ctx->K[1][i];
215        } else {
216                ctx->IV[ctx->buflen] ^= 0x80;
217                /* K3 */
218                for (i = 0; i < 16; i++)
219                        ctx->IV[i] ^= ctx->K[2][i];
220        }
221
222        AES_ecb_encrypt(ctx->IV, ctx->IV, &ctx->key, 1);
223        memcpy(out, ctx->IV, 16);
224
225        return 0;
226}
227
228void descrambler_close(void)
229{
230        debug(620, "descrambler_close");
231        close(desc_fd);
232        desc_fd = -1;
233}
234
235void hexdump(const uint8_t *data, unsigned int len)
236{
237        while (len--)
238                printf("%02x ", *data++);
239        printf("\n");
240// move to end is better log
241        debug(620, "start");
242}
243
244#ifdef MIPSEL
245int descrambler_set_pid(int index, int enable, int pid)
246{
247        struct ca_pid p;
248        unsigned int flags = 0x80;
249
250        if(desc_fd == -1)
251                descrambler_open();
252        if (desc_fd > 0)
253        {
254                /*if(checkbox("DM900") == 1)
255                        cainit(desc_fd);*/  // GOst test
256                if (index)
257                        flags |= 0x40;
258
259                if (enable)
260                        flags |= 0x20;
261
262                p.pid = pid;
263                p.index = flags;
264               
265                if (ioctl(desc_fd, CA_SET_PID, &p) == -1)
266                {
267                        printf("[titan] **** ERROR: CA_SET_PID pid=0x%04x index=0x%04x (errno=%d %s)\n", p.pid, p.index, errno, strerror(errno));
268                }
269                else
270                {
271                        printf("[titan] **** CA_SET_PID pid=0x%04x index=0x%04x\n", p.pid, p.index);
272                }
273                testwork = 1;
274                //descrambler_close();
275        }
276        return 0;
277}
278#else
279/* we don't use this for ci cam ! */
280/*
281int descrambler_set_pid(int index, int enable, int pid)
282{
283        debug(620, "start");
284        struct ca_pid p;
285        if (enable)
286                p.index = index;
287        else
288                p.index = -1;
289
290        p.pid = pid;
291
292        if (ioctl(desc_fd, CA_SET_PID, &p))
293                printf("CA_SET_PID\n");
294
295        return 0;
296}
297*/
298#endif
299
300int descrambler_open(void)
301{
302        debug(620, "descrambler_open");
303        if(desc_fd == -1)
304        {
305                desc_fd = open(descrambler_filename, O_RDWR | O_NONBLOCK );
306                debug(620, "descrambler_filename: %s desc_fd: %d", descrambler_filename, desc_fd);
307        }
308        if (desc_fd <= 0) {
309                printf("cannot open %s\n", descrambler_filename);
310                return 0;
311        }
312        //if (ioctl(desc_fd, CA_RESET, NULL))
313        //      printf("**** ERROR: CA_RESET (errno=%d %s)\n", errno, strerror(errno));
314
315        return 1;
316}
317
318int descrambler_init(void)
319{
320        debug(620, "descrambler_init");
321        desc_user_count++;
322        debug(620, "desc_user_count: %d", desc_user_count);
323
324        return 0;
325}
326
327void descrambler_deinit(void)
328{
329        debug(620, "descrambler_deinit");
330        desc_user_count--;
331        if (desc_user_count <= 0 && desc_fd > 0)
332        {
333                cainit(desc_fd);
334                descrambler_close();
335                desc_user_count = 0;
336        }
337}
338
339static int pkcs_1_mgf1(const uint8_t *seed, unsigned long seedlen, uint8_t *mask, unsigned long masklen)
340{
341        debug(620, "start");
342        unsigned long hLen, x;
343        uint32_t counter;
344        uint8_t *buf;
345
346        /* get hash output size */
347        hLen = 20;      /* SHA1 */
348
349        /* allocate memory */
350        buf = (uint8_t*)malloc(hLen);
351        if (buf == NULL) {
352                printf("error mem\n");
353                return -1;
354        }
355
356        /* start counter */
357        counter = 0;
358
359        while (masklen > 0) {
360                /* handle counter */
361                BYTE32(buf, counter);
362                ++counter;
363
364                /* get hash of seed || counter */
365                unsigned char buffer[0x18];
366                memcpy(buffer, seed, seedlen);
367                memcpy(buffer + 0x14, buf, 4);
368                SHA1(buffer, 0x18, buf);
369
370                /* store it */
371                for (x = 0; x < hLen && masklen > 0; x++, masklen--)
372                        *mask++ = buf[x];
373        }
374
375        free(buf);
376
377        return 0;
378}
379
380static int pkcs_1_pss_encode(const uint8_t *msghash, unsigned int msghashlen,
381                             unsigned long saltlen, unsigned long modulus_bitlen,
382                             uint8_t *out, unsigned int outlen)
383{
384        debug(620, "start");
385        unsigned char *DB, *mask, *salt, *hash;
386        unsigned long x, y, hLen, modulus_len;
387        int err = -1;
388        unsigned char *hashbuf;
389        unsigned int hashbuflen;
390
391        hLen = 20;      /* SHA1 */
392        modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0);
393
394        /* allocate ram for DB/mask/salt/hash of size modulus_len */
395        DB = (unsigned char*)malloc(modulus_len);
396        mask = (unsigned char*)malloc(modulus_len);
397        salt = (unsigned char*)malloc(modulus_len);
398        hash = (unsigned char*)malloc(modulus_len);
399
400        hashbuflen = 8 + msghashlen + saltlen;
401        hashbuf = (unsigned char*)malloc(hashbuflen);
402
403        if (!(DB && mask && salt && hash && hashbuf)) {
404                printf("out of memory\n");
405                goto LBL_ERR;
406        }
407
408        /* generate random salt */
409        if (saltlen > 0) {
410                if (get_random(salt, saltlen) != (long)saltlen) {
411                        printf("rnd failed\n");
412                        goto LBL_ERR;
413                }
414        }
415
416        /* M = (eight) 0x00 || msghash || salt, hash = H(M) */
417        memset(hashbuf, 0, 8);
418        memcpy(hashbuf + 8, msghash, msghashlen);
419        memcpy(hashbuf + 8 + msghashlen, salt, saltlen);
420        SHA1(hashbuf, hashbuflen, hash);
421
422        /* generate DB = PS || 0x01 || salt, PS == modulus_len - saltlen - hLen - 2 zero bytes */
423        x = 0;
424        memset(DB + x, 0, modulus_len - saltlen - hLen - 2);
425        x += modulus_len - saltlen - hLen - 2;
426        DB[x++] = 0x01;
427        memcpy(DB + x, salt, saltlen);
428        x += saltlen;
429
430        err = pkcs_1_mgf1(hash, hLen, mask, modulus_len - hLen - 1);
431        if (err)
432                goto LBL_ERR;
433
434        /* xor against DB */
435        for (y = 0; y < (modulus_len - hLen - 1); y++)
436                DB[y] ^= mask[y];
437
438        /* output is DB || hash || 0xBC */
439        if (outlen < modulus_len) {
440                err = -1;
441                printf("error overflow\n");
442                goto LBL_ERR;
443        }
444
445        /* DB len = modulus_len - hLen - 1 */
446        y = 0;
447        memcpy(out + y, DB, modulus_len - hLen - 1);
448        y += modulus_len - hLen - 1;
449
450        /* hash */
451        memcpy(out + y, hash, hLen);
452        y += hLen;
453
454        /* 0xBC */
455        out[y] = 0xBC;
456
457        /* now clear the 8*modulus_len - modulus_bitlen most significant bits */
458        out[0] &= 0xFF >> ((modulus_len << 3) - (modulus_bitlen - 1));
459
460        err = 0;
461LBL_ERR:
462        free(hashbuf);
463        free(hash);
464        free(salt);
465        free(mask);
466        free(DB);
467
468        return err;
469}
470
471/* DH */
472
473int dh_gen_exp(uint8_t *dest, int dest_len, uint8_t *dh_g, int dh_g_len, uint8_t *dh_p, int dh_p_len)
474{
475        debug(620, "start");
476#if OPENSSL_VERSION_NUMBER < 0x10100000L
477// source from https://github.com/catalinii/minisatip/blob/master/src/ca.c
478    DH *dh;
479    BIGNUM *p, *g;
480    const BIGNUM *priv_key;
481    int len;
482    unsigned int gap;
483
484    dh = DH_new();
485
486    p = BN_bin2bn(dh_p, dh_p_len, 0);
487    g = BN_bin2bn(dh_g, dh_g_len, 0);
488    DH_set0_pqg(dh, p, NULL, g);
489    DH_set_flags(dh, DH_FLAG_NO_EXP_CONSTTIME);
490
491    DH_generate_key(dh);
492
493    DH_get0_key(dh, NULL, &priv_key);
494    len = BN_num_bytes(priv_key);
495    if (len > dest_len) {
496        printf("len > dest_len\n");
497        return -1;
498    }
499
500    gap = dest_len - len;
501    memset(dest, 0, gap);
502    BN_bn2bin(priv_key, &dest[gap]);
503
504    DH_free(dh);
505
506    return 0;
507#else
508        DH *dh;
509        int len;
510        unsigned int gap;
511
512        dh = DH_new();
513
514        dh->p = BN_bin2bn(dh_p, dh_p_len, 0);
515        dh->g = BN_bin2bn(dh_g, dh_g_len, 0);
516        dh->flags |= DH_FLAG_NO_EXP_CONSTTIME;
517
518        DH_generate_key(dh);
519
520        len = BN_num_bytes(dh->priv_key);
521        if (len > dest_len) {
522                printf("len > dest_len\n");
523                return -1;
524        }
525
526        gap = dest_len - len;
527        memset(dest, 0, gap);
528        BN_bn2bin(dh->priv_key, &dest[gap]);
529
530        DH_free(dh);
531
532        return 0;
533#endif
534}
535
536/* dest = base ^ exp % mod */
537int dh_mod_exp(uint8_t *dest, int dest_len, uint8_t *base, int base_len, uint8_t *mod, int mod_len, uint8_t *exp, int exp_len)
538{
539        debug(620, "start");
540
541        BIGNUM *bn_dest, *bn_base, *bn_exp, *bn_mod;
542        BN_CTX *ctx;
543        int len;
544        unsigned int gap;
545
546        bn_base = BN_bin2bn(base, base_len, NULL);
547        bn_exp = BN_bin2bn(exp, exp_len, NULL);
548        bn_mod = BN_bin2bn(mod, mod_len, NULL);
549        ctx = BN_CTX_new();
550
551        bn_dest = BN_new();
552        BN_mod_exp(bn_dest, bn_base, bn_exp, bn_mod, ctx);
553        BN_CTX_free(ctx);
554
555        len = BN_num_bytes(bn_dest);
556        if (len > dest_len) {
557                printf("len > dest_len\n");
558                return -1;
559        }
560
561        gap = dest_len - len;
562        memset(dest, 0, gap);
563        BN_bn2bin(bn_dest, &dest[gap]);
564
565        BN_free(bn_dest);
566        BN_free(bn_mod);
567        BN_free(bn_exp);
568        BN_free(bn_base);
569
570        return 0;
571}
572
573int dh_dhph_signature(uint8_t *out, uint8_t *nonce, uint8_t *dhph, RSA *r)
574{
575        debug(620, "start");
576        unsigned char dest[302];
577        uint8_t hash[20];
578        unsigned char dbuf[256];
579
580        dest[0x00] = 0x00;      /* version */
581        dest[0x01] = 0x00;
582        dest[0x02] = 0x08;      /* len (bits) */
583        dest[0x03] = 0x01;      /* version data */
584
585        dest[0x04] = 0x01;      /* msg_label */
586        dest[0x05] = 0x00;
587        dest[0x06] = 0x08;      /* len (bits) */
588        dest[0x07] = 0x02;      /* message data */
589
590        dest[0x08] = 0x02;      /* auth_nonce */
591        dest[0x09] = 0x01;
592        dest[0x0a] = 0x00;      /* len (bits) */
593        memcpy(&dest[0x0b], nonce, 32);
594
595        dest[0x2b] = 0x04;      /* DHPH - DH public key host */
596        dest[0x2c] = 0x08;
597        dest[0x2d] = 0x00;      /* len (bits) */
598        memcpy(&dest[0x2e], dhph, 256);
599
600        SHA1(dest, 0x12e, hash);
601
602        if (pkcs_1_pss_encode(hash, 20, 20, 0x800, dbuf, sizeof(dbuf))) {
603                printf("pss encode failed\n");
604                return -1;
605        }
606
607        RSA_private_encrypt(sizeof(dbuf), dbuf, out, r, RSA_NO_PADDING);
608
609        return 0;
610}
611
612int get_random(unsigned char *dest, int len)
613{
614        debug(620, "start");
615        int fd;
616        const char *urnd = "/dev/urandom";
617
618        fd = open(urnd, O_RDONLY);
619        if (fd <= 0) {
620                printf("cannot open %s\n", urnd);
621                return -1;
622        }
623
624        if (read(fd, dest, len) != len) {
625                printf("cannot read from %s\n", urnd);
626                close(fd);
627                return -2;
628        }
629
630        close(fd);
631
632        return len;
633}
634
635int parseLengthField(const unsigned char *pkt, int *len)
636{
637        debug(620, "start");
638        int i;
639
640        *len = 0;
641        if (!(*pkt & 0x80)) {
642                *len = *pkt;
643                return 1;
644        }
645        for (i = 0; i < (pkt[0] & 0x7F); ++i) {
646                *len <<= 8;
647                *len |= pkt[i + 1];
648        }
649
650        return (pkt[0] & 0x7F) + 1;
651}
652
653int add_padding(uint8_t *dest, unsigned int len, unsigned int blocklen)
654{
655        debug(620, "start");
656        uint8_t padding = 0x80;
657        int count = 0;
658
659        while (len & (blocklen - 1)) {
660                *dest++ = padding;
661                ++len;
662                ++count;
663                padding = 0;
664        }
665
666        return count;
667}
668
669static int get_bin_from_nibble(int in)
670{
671        debug(620, "start");
672        if ((in >= '0') && (in <= '9'))
673                return in - 0x30;
674
675        if ((in >= 'A') && (in <= 'Z'))
676                return in - 0x41 + 10;
677
678        if ((in >= 'a') && (in <= 'z'))
679                return in - 0x61 + 10;
680
681        printf("fixme: unsupported chars in hostid\n");
682
683        return 0;
684}
685
686void str2bin(uint8_t *dst, char *data, int len)
687{
688        debug(620, "start");
689        int i;
690
691        for (i = 0; i < len; i += 2)
692                *dst++ = (get_bin_from_nibble(data[i]) << 4) | get_bin_from_nibble(data[i + 1]);
693
694}
695
696uint32_t UINT32(const unsigned char *in, unsigned int len)
697{
698        debug(620, "start");
699        uint32_t val = 0;
700        unsigned int i;
701
702        for (i = 0; i < len; i++) {
703                val <<= 8;
704                val |= *in++;
705        }
706
707        return val;
708}
709
710int BYTE32(unsigned char *dest, uint32_t val)
711{
712        debug(620, "start");
713        *dest++ = val >> 24;
714        *dest++ = val >> 16;
715        *dest++ = val >> 8;
716        *dest++ = val;
717
718        return 4;
719}
720
721int BYTE16(unsigned char *dest, uint16_t val)
722{
723        debug(620, "start");
724        *dest++ = val >> 8;
725        *dest++ = val;
726
727        return 2;
728}
729
730static void CheckFile(char *file)
731{
732        debug(620, "start");
733        if (access(file, F_OK) != 0) {
734                printf("No File: %s\n", file);
735                FILE* fd;
736                fd = fopen(file, "w");
737                fclose(fd);
738        }
739}
740
741static void get_authdata_filename(char *dest, size_t len, unsigned int slot)
742{
743        debug(620, "start");
744
745#ifdef QUIET
746       
747        FILE *auth_bin;
748  char source[256];
749  sprintf(source, "ci_auth_slot_%d.bin", slot);
750  char target[256];
751  char sourcepath[256];
752  char targetpath[256];
753  char authpath[16];
754  char classicpath[256];
755  sprintf(classicpath,"/var/run/ca/%s", source);
756       
757        /* initalize authie with "/tmp/ " */
758        authie[0]=47;
759        authie[1]=116;
760        authie[2]=109;
761        authie[3]=112;
762        authie[4]=47;
763        authie[5]=32;
764        authie[6]=0;
765        /* initalize devie with "/dev/ " */
766        devie[0]=47;
767        devie[1]=100;
768        devie[2]=101;
769        devie[3]=118;
770        devie[4]=47;
771        devie[5]=32;
772        devie[6]=0;
773       
774        sprintf(authpath,"%s/%s", authie,devie); /* big brother is watching */
775        target[0]=32;
776        if (slot==1)
777        {
778                target[1]=32; /* "  " */
779                target[2]=0;
780        }
781        else
782        {
783                target[1]=0; /* " " */
784        }
785        sprintf(sourcepath, "%s/%s", authpath, source);
786        sprintf(targetpath, "%s/%s", authpath, target);
787
788        mkdir(authie, 0777);
789  mount("/", authie, NULL, MS_BIND, NULL);
790        mkdir(authpath, 0777);
791  /* create empty auth file at /var/run/ca for compatibility */
792        auth_bin = fopen(targetpath, "r");
793        if (auth_bin)
794        {
795                fclose(auth_bin);
796        auth_bin = fopen(classicpath, "r");
797        if (auth_bin > 0) /* already exists */
798                {
799                        fclose(auth_bin);
800                }
801                else
802                {
803                        mkdir("/var/run/ca", 0777);
804#ifdef RANDOM
805                        /* create file with random data */
806                        FILE *f;
807        f=fopen (classicpath, "wb");
808                        int r,a;
809                        char c[1];
810                        srand((unsigned)time(NULL));
811                        for(a=0;a<296;a++)
812                        {
813                                r=rand();
814                                c[0]=r;
815                                fwrite(c,1,1,f);
816                        }
817                        fclose(f);
818#else
819                        /* create empty file */
820                        int ff=open (classicpath, O_RDWR|O_CREAT,0);
821                        close(ff);
822#endif
823                }
824        }
825        else
826        {
827                /* no auth file hence remove compatibility file */
828                remove(classicpath);
829        }
830        snprintf(dest, len, "%s/%s", authpath, target);
831#else
832        snprintf(dest, len, "/mnt/ci_auth_slot_%u.bin", slot);
833        CheckFile(dest);
834#endif
835}
836
837//static bool get_authdata(uint8_t *host_id, uint8_t *dhsk, uint8_t *akh, unsigned int slot, unsigned int index)
838static int get_authdata(uint8_t *host_id, uint8_t *dhsk, uint8_t *akh, unsigned int slot, unsigned int index)
839{
840        debug(620, "start");
841        char filename[FILENAME_MAX];
842        int fd;
843        uint8_t chunk[8 + 256 + 32];
844        unsigned int i;
845
846        /* 5 pairs of data only */
847        if (index > 5)
848                return 0;
849
850        get_authdata_filename(filename, sizeof(filename), slot);
851
852        fd = open(filename, O_RDONLY);
853        if (fd <= 0) {
854                fprintf(stderr, "cannot open %s\n", filename);
855#ifdef QUIET
856                umount(authie);
857                rmdir(authie);
858#endif         
859                return 0;
860        }
861
862        for (i = 0; i < 5; i++) {
863                if (read(fd, chunk, sizeof(chunk)) != sizeof(chunk)) {
864                        fprintf(stderr, "cannot read auth_data\n");
865                        close(fd);
866#ifdef QUIET
867                        umount(authie);
868                        rmdir(authie);
869#endif         
870                        return 0;
871                }
872
873                if (i == index) {
874                        memcpy(host_id, chunk, 8);
875                        memcpy(dhsk, &chunk[8], 256);
876                        memcpy(akh, &chunk[8 + 256], 32);
877                        close(fd);
878#ifdef QUIET
879                        umount(authie);
880                        rmdir(authie);
881#endif         
882                        return 1;
883                }
884        }
885        close(fd);
886#ifdef QUIET
887        umount(authie);
888        rmdir(authie);
889#endif         
890
891        return 0;
892}
893
894static int write_authdata(unsigned int slot, const uint8_t *host_id, const uint8_t *dhsk, const uint8_t *akh)
895{
896        debug(620, "start");
897        char filename[FILENAME_MAX];
898        int fd;
899        uint8_t buf[(8 + 256 + 32) * 5];
900        unsigned int entries;
901        unsigned int i;
902        int ret = 0;
903
904        for (entries = 0; entries < 5; entries++) {
905                int offset = (8 + 256 + 32) * entries;
906                if (!get_authdata(&buf[offset], &buf[offset + 8], &buf[offset + 8 + 256], slot, entries))
907                        break;
908
909                /* check if we got this pair already */
910                if (!memcmp(&buf[offset + 8 + 256], akh, 32)) {
911                        printf("data already stored\n");
912                        return 1;
913                }
914        }
915
916        //printf("got %d entries\n", entries);
917
918        get_authdata_filename(filename, sizeof(filename), slot);
919
920        fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR);
921        if (fd <= 0) {
922                printf("cannot open %s for writing - authdata not stored\n", filename);
923#ifdef QUIET
924                umount(authie);
925                rmdir(authie);
926#endif         
927                return 0;
928        }
929
930        /* store new entry first */
931        if (write(fd, host_id, 8) != 8) {
932                fprintf(stderr, "error in write\n");
933                goto end;
934        }
935
936        if (write(fd, dhsk, 256) != 256) {
937                fprintf(stderr, "error in write\n");
938                goto end;
939        }
940
941        if (write(fd, akh, 32) != 32) {
942                fprintf(stderr, "error in write\n");
943                goto end;
944        }
945
946        /* skip the last one if exists */
947        if (entries > 3)
948                entries = 3;
949
950        for (i = 0; i < entries; i++) {
951                int offset = (8 + 256 + 32) * i;
952                if (write(fd, &buf[offset], (8 + 256 + 32)) != (8 + 256 + 32)) {
953                        fprintf(stderr, "error in write\n");
954                        goto end;
955                }
956        }
957
958        ret = 1;
959end:
960        close(fd);
961#ifdef QUIET
962        umount(authie);
963        rmdir(authie);
964        if (ret == 1)
965        {
966                /* call once more to get symlink or compatibility file */
967                get_authdata_filename(filename, sizeof(filename), slot);
968        }
969        umount(authie);
970        rmdir(authie);
971#endif
972        return ret;
973}
974
975static int verify_cb(int ok, X509_STORE_CTX *ctx)
976{
977        debug(620, "start");
978        if (X509_STORE_CTX_get_error(ctx) == X509_V_ERR_CERT_NOT_YET_VALID) {
979                time_t now = time(NULL);
980                struct tm *t = localtime(&now);
981                if (t->tm_year < 2015)
982                        //printf("seems our rtc is wrong - ignore!\n");
983                        return 1;
984                //printf("wrong date!\n");
985        }
986
987        if (X509_STORE_CTX_get_error(ctx) == X509_V_ERR_CERT_HAS_EXPIRED)
988                return 1;
989
990        return 0;
991}
992
993static RSA *rsa_privatekey_open(const char *filename)
994{
995        debug(620, "start");
996        FILE *fp;
997        RSA *r = NULL;
998
999        fp = fopen(filename, "r");
1000        if (!fp) {
1001#ifndef CERTIN
1002                fprintf(stderr, "cannot open %s\n", filename);
1003#endif
1004                return NULL;
1005        }
1006
1007        PEM_read_RSAPrivateKey(fp, &r, NULL, NULL);
1008        if (!r)
1009                fprintf(stderr, "read error\n");
1010
1011        fclose(fp);
1012
1013        return r;
1014}
1015
1016static X509 *certificate_open(const char *filename)
1017{
1018        debug(620, "start");
1019        FILE *fp;
1020        X509 *cert;
1021
1022        fp = fopen(filename, "r");
1023        if (!fp) {
1024#ifndef CERTIN
1025                fprintf(stderr, "cannot open %s\n", filename);
1026#endif
1027                return NULL;
1028        }
1029
1030        cert = PEM_read_X509(fp, NULL, NULL, NULL);
1031        if (!cert)
1032                fprintf(stderr, "cannot read cert\n");
1033
1034        fclose(fp);
1035
1036        return cert;
1037}
1038
1039//static bool certificate_validate(struct cert_ctx *ctx, X509 *cert)
1040static int certificate_validate(struct cert_ctx *ctx, X509 *cert)
1041{
1042        debug(620, "start");
1043#if OPENSSL_VERSION_NUMBER < 0x10100000L
1044// source from https://github.com/catalinii/minisatip/blob/master/src/ca.c
1045    X509_STORE_CTX *store_ctx;
1046    int ret;
1047
1048    store_ctx = X509_STORE_CTX_new();
1049
1050    X509_STORE_CTX_init(store_ctx, ctx->store, cert, NULL);
1051    X509_STORE_CTX_set_verify_cb(store_ctx, verify_cb);
1052    X509_STORE_CTX_set_flags(store_ctx, X509_V_FLAG_IGNORE_CRITICAL);
1053
1054    ret = X509_verify_cert(store_ctx);
1055
1056    if (ret != 1) {
1057        fprintf(stderr, "%s\n", X509_verify_cert_error_string(X509_STORE_CTX_get_error(store_ctx)));
1058    }
1059
1060    X509_STORE_CTX_free(store_ctx);
1061
1062    if (ret == 1)
1063        return 1;
1064    else
1065        return 0;
1066#else
1067        X509_STORE_CTX *store_ctx;
1068        int ret;
1069
1070        store_ctx = X509_STORE_CTX_new();
1071
1072        X509_STORE_CTX_init(store_ctx, ctx->store, cert, NULL);
1073        X509_STORE_CTX_set_verify_cb(store_ctx, verify_cb);
1074        X509_STORE_CTX_set_flags(store_ctx, X509_V_FLAG_IGNORE_CRITICAL);
1075
1076        ret = X509_verify_cert(store_ctx);
1077
1078        if (ret != 1)
1079                fprintf(stderr, "%s\n", X509_verify_cert_error_string(store_ctx->error));
1080
1081        X509_STORE_CTX_free(store_ctx);
1082
1083        return ret == 1;
1084#endif
1085}
1086
1087static X509 *certificate_load_and_check(struct cert_ctx *ctx, const char *filename)
1088{
1089        debug(620, "start");
1090        X509 *cert;
1091
1092        if (!ctx->store) {
1093                /* we assume this is the first certificate added - so its root-ca */
1094                ctx->store = X509_STORE_new();
1095                if (!ctx->store) {
1096                        fprintf(stderr, "cannot create cert_store\n");
1097                        exit(-1);
1098                }
1099
1100                if (X509_STORE_load_locations(ctx->store, filename, NULL) != 1) {
1101#ifndef CERTIN
1102                        fprintf(stderr, "load of first certificate (root_ca) failed\n");
1103                        exit(-1);
1104#else
1105                        return NULL;
1106#endif
1107                }
1108                return (X509 *) 1;
1109                //return NULL;
1110        }
1111
1112        cert = certificate_open(filename);
1113        if (!cert) {
1114                fprintf(stderr, "cannot open certificate %s\n", filename);
1115                return NULL;
1116        }
1117
1118        if (!certificate_validate(ctx, cert)) {
1119                fprintf(stderr, "cannot vaildate certificate\n");
1120                X509_free(cert);
1121                return NULL;
1122        }
1123
1124        /* push into store - create a chain */
1125        if (X509_STORE_load_locations(ctx->store, filename, NULL) != 1) {
1126#ifndef CERTIN
1127                fprintf(stderr, "load of certificate failed\n");
1128#endif
1129                X509_free(cert);
1130                return NULL;
1131        }
1132
1133        return cert;
1134}
1135
1136static X509 *certificate_import_and_check(struct cert_ctx *ctx, const uint8_t *data, int len)
1137{
1138        debug(620, "start");
1139        X509 *cert;
1140
1141        cert = d2i_X509(NULL, &data, len);
1142        if (!cert) {
1143                fprintf(stderr, "cannot read certificate\n");
1144                return NULL;
1145        }
1146
1147        if (!certificate_validate(ctx, cert)) {
1148                fprintf(stderr, "cannot vaildate certificate\n");
1149                X509_free(cert);
1150                return NULL;
1151        }
1152
1153        X509_STORE_add_cert(ctx->store, cert);
1154
1155        return cert;
1156}
1157
1158static struct element *element_get(struct cc_ctrl_data *cc_data, unsigned int id)
1159{
1160        debug(620, "start");
1161        /* array index */
1162        if ((id < 1) || (id >= MAX_ELEMENTS)) {
1163                fprintf(stderr, "element_get: invalid id\n");
1164                return NULL;
1165        }
1166
1167        return &cc_data->elements[id];
1168}
1169
1170static void element_invalidate(struct cc_ctrl_data *cc_data, unsigned int id)
1171{
1172        debug(620, "start");
1173        struct element *e;
1174
1175        e = element_get(cc_data, id);
1176        if (e) {
1177                free(e->data);
1178                memset(e, 0, sizeof(struct element));
1179        }
1180}
1181
1182static void element_init(struct cc_ctrl_data *cc_data)
1183{
1184        debug(620, "start");
1185        unsigned int i;
1186
1187        for (i = 1; i < MAX_ELEMENTS; i++)
1188                element_invalidate(cc_data, i);
1189}
1190
1191static int element_set(struct cc_ctrl_data *cc_data, unsigned int id, const uint8_t *data, uint32_t size)
1192{
1193        debug(620, "start");
1194        struct element *e;
1195
1196        e = element_get(cc_data, id);
1197        if (e == NULL)
1198                return 0;
1199
1200        /* check size */
1201        if ((datatype_sizes[id] != 0) && (datatype_sizes[id] != size)) {
1202                fprintf(stderr, "size %d of datatype_id %d doesn't match\n", size, id);
1203                return 0;
1204        }
1205
1206        free(e->data);
1207        e->data = (uint8_t*)malloc(size);
1208        memcpy(e->data, data, size);
1209        e->size = size;
1210        e->valid = 1;
1211
1212        //printf("stored %d with len %d\n", id, size);
1213
1214        return 1;
1215}
1216
1217static int element_set_certificate(struct cc_ctrl_data *cc_data, unsigned int id, X509 *cert)
1218{
1219        debug(620, "start");
1220        unsigned char *cert_der = NULL;
1221        int cert_len;
1222
1223        cert_len = i2d_X509(cert, &cert_der);
1224        if (cert_len <= 0) {
1225                printf("cannot get data in DER format\n");
1226                return 0;
1227        }
1228
1229        if (!element_set(cc_data, id, cert_der, cert_len)) {
1230                printf("cannot store element (%d)\n", id);
1231                return 0;
1232        }
1233
1234        return 1;
1235}
1236
1237static int element_set_hostid_from_certificate(struct cc_ctrl_data *cc_data, unsigned int id, X509 *cert)
1238{
1239        debug(620, "start");
1240        X509_NAME *subject;
1241        int nid_cn = OBJ_txt2nid("CN");
1242        char hostid[20];
1243        uint8_t bin_hostid[8];
1244
1245        if ((id != 5) && (id != 6)) {
1246                printf("wrong datatype_id for hostid\n");
1247                return 0;
1248        }
1249
1250        subject = X509_get_subject_name(cert);
1251        X509_NAME_get_text_by_NID(subject, nid_cn, hostid, sizeof(hostid));
1252
1253        if (strlen(hostid) != 16) {
1254                printf("malformed hostid\n");
1255                return 0;
1256        }
1257
1258        str2bin(bin_hostid, hostid, 16);
1259
1260        if (!element_set(cc_data, id, bin_hostid, sizeof(bin_hostid))) {
1261                printf("cannot set hostid\n");
1262                return 0;
1263        }
1264
1265        return 1;
1266}
1267
1268static int element_valid(struct cc_ctrl_data *cc_data, unsigned int id)
1269{
1270        debug(620, "start");
1271        struct element *e;
1272
1273        e = element_get(cc_data, id);
1274
1275        return e && e->valid;
1276}
1277
1278static unsigned int element_get_buf(struct cc_ctrl_data *cc_data, uint8_t *dest, unsigned int id)
1279{
1280        debug(620, "start");
1281        struct element *e;
1282
1283        e = element_get(cc_data, id);
1284        if (e == NULL)
1285                return 0;
1286
1287        if (!e->valid) {
1288                fprintf(stderr, "element_get_buf: datatype %d not valid\n", id);
1289                return 0;
1290        }
1291
1292        if (!e->data) {
1293                fprintf(stderr, "element_get_buf: datatype %d doesn't exist\n", id);
1294                return 0;
1295        }
1296
1297        if (dest)
1298                memcpy(dest, e->data, e->size);
1299
1300        return e->size;
1301}
1302
1303static unsigned int element_get_req(struct cc_ctrl_data *cc_data, uint8_t *dest, unsigned int id)
1304{
1305        debug(620, "start");
1306        unsigned int len = element_get_buf(cc_data, &dest[3], id);
1307
1308        if (len == 0) {
1309                fprintf(stderr, "cannot get element %d\n", id);
1310                return 0;
1311        }
1312
1313        dest[0] = id;
1314        dest[1] = len >> 8;
1315        dest[2] = len;
1316
1317        return 3 + len;
1318}
1319
1320static uint8_t *element_get_ptr(struct cc_ctrl_data *cc_data, unsigned int id)
1321{
1322        debug(620, "start");
1323        struct element *e;
1324
1325        e = element_get(cc_data, id);
1326        if (e == NULL)
1327                return NULL;
1328
1329        if (!e->valid) {
1330                fprintf(stderr, "element_get_ptr: datatype %u not valid\n", id);
1331                return NULL;
1332        }
1333
1334        if (!e->data) {
1335                fprintf(stderr, "element_get_ptr: datatype %u doesn't exist\n", id);
1336                return NULL;
1337        }
1338
1339        return e->data;
1340}
1341
1342
1343/* content_control commands */
1344
1345static int sac_check_auth(const uint8_t *data, unsigned int len, uint8_t *sak)
1346{
1347        debug(620, "start");
1348        struct aes_xcbc_mac_ctx ctx;
1349        uint8_t calced_signature[16];
1350
1351        if (len < 16)
1352                return 0;
1353
1354        aes_xcbc_mac_init(&ctx, sak);
1355        aes_xcbc_mac_process(&ctx, (uint8_t *)"\x04", 1);        /* header len */
1356        aes_xcbc_mac_process(&ctx, data, len - 16);
1357        aes_xcbc_mac_done(&ctx, calced_signature);
1358
1359        if (memcmp(&data[len - 16], calced_signature, 16)) {
1360                fprintf(stderr, "signature wrong\n");
1361                return 0;
1362        }
1363
1364        //printf("auth ok!\n");
1365
1366        return 1;
1367}
1368
1369static int sac_gen_auth(uint8_t *out, uint8_t *in, unsigned int len, uint8_t *sak)
1370{
1371        debug(620, "start");
1372        struct aes_xcbc_mac_ctx ctx;
1373        aes_xcbc_mac_init(&ctx, sak);
1374        aes_xcbc_mac_process(&ctx, (uint8_t *)"\x04", 1);        /* header len */
1375        aes_xcbc_mac_process(&ctx, in, len);
1376        aes_xcbc_mac_done(&ctx, out);
1377
1378        return 16;
1379}
1380
1381static void generate_key_seed(struct cc_ctrl_data *cc_data)
1382{
1383        debug(620, "start");
1384        /* this is triggered by new ns_module */
1385
1386        /* generate new key_seed -> SEK/SAK key derivation */
1387        SHA256_CTX sha;
1388
1389        SHA256_Init(&sha);
1390        SHA256_Update(&sha, &cc_data->dhsk[240], 16);
1391        SHA256_Update(&sha, element_get_ptr(cc_data, 22), element_get_buf(cc_data, NULL, 22));
1392        SHA256_Update(&sha, element_get_ptr(cc_data, 20), element_get_buf(cc_data, NULL, 20));
1393        SHA256_Update(&sha, element_get_ptr(cc_data, 21), element_get_buf(cc_data, NULL, 21));
1394        SHA256_Final(cc_data->ks_host, &sha);
1395}
1396
1397static void generate_ns_host(struct cc_ctrl_data *cc_data)
1398{
1399        debug(620, "start");
1400        uint8_t buf[8];
1401
1402        get_random(buf, sizeof(buf));
1403        element_set(cc_data, 20, buf, sizeof(buf));
1404}
1405
1406static int generate_SAK_SEK(uint8_t *sak, uint8_t *sek, const uint8_t *ks_host)
1407{
1408        debug(620, "start");
1409        AES_KEY key;
1410        const uint8_t key_data[16] = { 0xea, 0x74, 0xf4, 0x71, 0x99, 0xd7, 0x6f, 0x35, 0x89, 0xf0, 0xd1, 0xdf, 0x0f, 0xee, 0xe3, 0x00 };
1411        uint8_t dec[32];
1412        int i;
1413
1414        /* key derivation of sak & sek */
1415
1416        AES_set_encrypt_key(key_data, 128, &key);
1417
1418        for (i = 0; i < 2; i++)
1419                AES_ecb_encrypt(&ks_host[16 * i], &dec[16 * i], &key, 1);
1420
1421        for (i = 0; i < 16; i++)
1422                sek[i] = ks_host[i] ^ dec[i];
1423
1424        for (i = 0; i < 16; i++)
1425                sak[i] = ks_host[16 + i] ^ dec[16 + i];
1426
1427        return 0;
1428}
1429
1430static int sac_crypt(uint8_t *dst, const uint8_t *src, unsigned int len, const uint8_t *key_data, int encrypt)
1431{
1432        debug(620, "start");
1433        uint8_t iv[16] = { 0xf7, 0x70, 0xb0, 0x36, 0x03, 0x61, 0xf7, 0x96, 0x65, 0x74, 0x8a, 0x26, 0xea, 0x4e, 0x85, 0x41 };
1434        AES_KEY key;
1435
1436        /* AES_ENCRYPT is '1' */
1437
1438        if (encrypt)
1439                AES_set_encrypt_key(key_data, 128, &key);
1440        else
1441                AES_set_decrypt_key(key_data, 128, &key);
1442
1443        AES_cbc_encrypt(src, dst, len, &key, iv, encrypt);
1444
1445        return 0;
1446}
1447
1448static X509 *import_ci_certificates(struct cc_ctrl_data *cc_data, unsigned int id)
1449{
1450        debug(620, "start");
1451        struct cert_ctx *ctx = cc_data->cert_ctx;
1452        X509 *cert;
1453        uint8_t buf[2048];
1454        unsigned int len;
1455
1456        len = element_get_buf(cc_data, buf, id);
1457
1458        cert = certificate_import_and_check(ctx, buf, len);
1459        if (!cert) {
1460                printf("cannot read/verify DER cert\n");
1461                return NULL;
1462        }
1463
1464        return cert;
1465}
1466
1467static int check_ci_certificates(struct cc_ctrl_data *cc_data)
1468{
1469        debug(620, "start");
1470        struct cert_ctx *ctx = cc_data->cert_ctx;
1471
1472        /* check if both certificates are available before we push and verify them */
1473
1474        /* check for CICAM_BrandCert */
1475        if (!element_valid(cc_data, 8))
1476                return -1;
1477
1478        /* check for CICAM_DevCert */
1479        if (!element_valid(cc_data, 16))
1480                return -1;
1481
1482#if 0
1483        {
1484                /* write ci device cert to disk */
1485                int fd = open("ci_cert.der", O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR);
1486                write(fd, element_get_ptr(cc_data, 16), element_get_buf(cc_data, NULL, 16));
1487                close(fd);
1488        }
1489#endif
1490
1491        /* import CICAM_BrandCert */
1492        if ((ctx->ci_cust_cert = import_ci_certificates(cc_data, 8)) == NULL) {
1493                printf("cannot import cert\n");
1494                return -1;
1495        }
1496
1497        /* import CICAM_DevCert */
1498        if ((ctx->ci_device_cert = import_ci_certificates(cc_data, 16)) == NULL) {
1499                printf("cannot import cert\n");
1500                return -1;
1501        }
1502
1503        /* everything seems to be fine here - so extract the CICAM_id from cert */
1504        if (!element_set_hostid_from_certificate(cc_data, 6, ctx->ci_device_cert)) {
1505                printf("cannot set cicam_id in elements\n");
1506                return -1;
1507        }
1508
1509        return 0;
1510}
1511
1512static int generate_akh(struct cc_ctrl_data *cc_data)
1513{
1514        debug(620, "start");
1515        uint8_t akh[32];
1516        SHA256_CTX sha;
1517
1518        SHA256_Init(&sha);
1519        SHA256_Update(&sha, element_get_ptr(cc_data, 6), element_get_buf(cc_data, NULL, 6));
1520        SHA256_Update(&sha, element_get_ptr(cc_data, 5), element_get_buf(cc_data, NULL, 5));
1521        SHA256_Update(&sha, cc_data->dhsk, 256);
1522        SHA256_Final(akh, &sha);
1523
1524        element_set(cc_data, 22, akh, sizeof(akh));
1525
1526        return 0;
1527}
1528
1529static int check_dh_challenge(struct cc_ctrl_data *cc_data)
1530{
1531        debug(620, "start");
1532        /* check if every element for calculation of DHSK & AKH is available */
1533
1534        /* check for auth_nonce */
1535        if (!element_valid(cc_data, 19))
1536                return 0;
1537
1538        /* check for CICAM_id */
1539        if (!element_valid(cc_data, 6))
1540                return 0;
1541
1542        /* check for DHPM */
1543        if (!element_valid(cc_data, 14))
1544                return 0;
1545
1546        /* check for Signature_B */
1547        if (!element_valid(cc_data, 18))
1548                return 0;
1549
1550        /* calculate DHSK - DHSK = DHPM ^ dh_exp % dh_p */
1551        dh_mod_exp(cc_data->dhsk, 256, element_get_ptr(cc_data, 14), 256, dh_p, sizeof(dh_p), cc_data->dh_exp, 256);
1552
1553        /* gen AKH */
1554        generate_akh(cc_data);
1555
1556        /* disable 5 tries of startup -> use new calculated one */
1557        cc_data->akh_index = 5;
1558
1559        /* write to disk */
1560        write_authdata(cc_data->slot->connid - 1, element_get_ptr(cc_data, 5), cc_data->dhsk, element_get_ptr(cc_data, 22));
1561
1562        return 1;
1563}
1564
1565static int restart_dh_challenge(struct cc_ctrl_data *cc_data)
1566{
1567        debug(620, "start");
1568        uint8_t dhph[256], sign_A[256];
1569        struct cert_ctx *ctx;
1570
1571        if (!cc_data->cert_ctx) {
1572                ctx = (struct cert_ctx*)calloc(1, sizeof(struct cert_ctx));
1573                cc_data->cert_ctx = ctx;
1574        } else {
1575                ctx = cc_data->cert_ctx;
1576        }
1577
1578        /* load certificates and device key */
1579        if (!certificate_load_and_check(ctx, ROOT_CERT))
1580        {       
1581#ifdef CERTIN
1582        /* internal root certificate handling */
1583        root_cert_len=strlen(root_cert);
1584        root_bio = BIO_new(BIO_s_mem());
1585        BIO_write(root_bio, root_cert, root_cert_len);
1586        X509* root_certX509 = PEM_read_bio_X509(root_bio, NULL, NULL, NULL);
1587        if (!root_certX509)
1588        {
1589        fprintf(stderr, "FAILED parsing embedded root cert\n");
1590        }
1591        if (!ctx->store)
1592        {
1593                ctx->store = X509_STORE_new();
1594                if (!ctx->store)
1595                {
1596                        fprintf(stderr, "can not create cert_store\n");
1597                }
1598        }
1599  fprintf(stderr, "EMBEDDED root cert ...\n");
1600        X509_STORE_add_cert(ctx->store, root_certX509);
1601#endif
1602        }
1603
1604        ctx->cust_cert = certificate_load_and_check(ctx, CUSTOMER_CERT);
1605       
1606#ifdef CERTIN
1607        if (!ctx->cust_cert)
1608        {
1609                /* internal customer certificate handling */
1610                customer_cert_len=strlen(customer_cert);
1611                customer_bio = BIO_new(BIO_s_mem());
1612                BIO_write(customer_bio, customer_cert, customer_cert_len);
1613                X509* customer_certX509 = PEM_read_bio_X509(customer_bio, NULL, NULL, NULL);
1614                if (!customer_certX509)
1615                {
1616                        fprintf(stderr, "FAILED parsing embedded customer cert\n");
1617                }
1618                fprintf(stderr, "EMBEDDED customer cert ...\n");
1619                X509_STORE_add_cert(ctx->store, customer_certX509);
1620                ctx->cust_cert=customer_certX509;
1621        }
1622#endif
1623
1624        ctx->device_cert = certificate_load_and_check(ctx, DEVICE_CERT);
1625
1626#ifdef CERTIN   
1627        if (!ctx->device_cert)
1628        {
1629                /* internal device certificate handling */
1630                device_cert_len=strlen(device_cert);
1631                device_bio = BIO_new(BIO_s_mem());
1632                BIO_write(device_bio, device_cert, device_cert_len);
1633                X509* device_certX509 = PEM_read_bio_X509(device_bio, NULL, NULL, NULL);
1634                if (!device_certX509)
1635                {
1636                        fprintf(stderr, "FAILED parsing embedded device cert\n");
1637                }
1638                fprintf(stderr, "EMBEDDED device cert ...\n");
1639                X509_STORE_add_cert(ctx->store, device_certX509);
1640                ctx->device_cert=device_certX509;
1641        }
1642#endif
1643
1644        if (!ctx->cust_cert || !ctx->device_cert) {
1645                fprintf(stderr, "cannot loader certificates\n");
1646                return -1;
1647        }
1648
1649        /* add data to element store */
1650        if (!element_set_certificate(cc_data, 7, ctx->cust_cert))
1651                fprintf(stderr, "cannot store cert in elements\n");
1652
1653        if (!element_set_certificate(cc_data, 15, ctx->device_cert))
1654                fprintf(stderr, "cannot store cert in elements\n");
1655
1656        if (!element_set_hostid_from_certificate(cc_data, 5, ctx->device_cert))
1657                fprintf(stderr, "cannot set hostid in elements\n");
1658
1659        cc_data->rsa_device_key = rsa_privatekey_open(DEVICE_CERT);
1660        if (!cc_data->rsa_device_key)
1661        {
1662#ifdef CERTIN
1663                /* internal private key */
1664                cc_data->rsa_device_key = PEM_read_bio_RSAPrivateKey(device_bio,NULL, NULL, NULL);
1665                fprintf(stderr, "EMBEDDED private key ...\n");
1666#else
1667                fprintf(stderr, "cannot read private key\n");
1668                return -1;
1669#endif
1670        }
1671
1672        /* invalidate elements */
1673        element_invalidate(cc_data, 6);
1674        element_invalidate(cc_data, 14);
1675        element_invalidate(cc_data, 18);
1676        element_invalidate(cc_data, 22); /* this will refuse a unknown cam */
1677
1678        /* new dh_exponent */
1679        dh_gen_exp(cc_data->dh_exp, 256, dh_g, sizeof(dh_g), dh_p, sizeof(dh_p));
1680
1681        /* new DHPH  - DHPH = dh_g ^ dh_exp % dh_p */
1682        dh_mod_exp(dhph, sizeof(dhph), dh_g, sizeof(dh_g), dh_p, sizeof(dh_p), cc_data->dh_exp, 256);
1683
1684        /* store DHPH */
1685        element_set(cc_data, 13, dhph, sizeof(dhph));
1686
1687        /* create Signature_A */
1688        dh_dhph_signature(sign_A, element_get_ptr(cc_data, 19), dhph, cc_data->rsa_device_key);
1689
1690        /* store Signature_A */
1691        element_set(cc_data, 17, sign_A, sizeof(sign_A));
1692
1693        return 0;
1694}
1695
1696static int generate_uri_confirm(struct cc_ctrl_data *cc_data, const uint8_t *sak)
1697{
1698        debug(620, "start");
1699        SHA256_CTX sha;
1700        uint8_t uck[32];
1701        uint8_t uri_confirm[32];
1702
1703        /* calculate UCK (uri confirmation key) */
1704        SHA256_Init(&sha);
1705        SHA256_Update(&sha, sak, 16);
1706        SHA256_Final(uck, &sha);
1707
1708        /* calculate uri_confirm */
1709        SHA256_Init(&sha);
1710        SHA256_Update(&sha, element_get_ptr(cc_data, 25), element_get_buf(cc_data, NULL, 25));
1711        SHA256_Update(&sha, uck, 32);
1712        SHA256_Final(uri_confirm, &sha);
1713
1714        element_set(cc_data, 27, uri_confirm, 32);
1715
1716        return 0;
1717}
1718
1719static void check_new_key(struct dvbdev* dvbnode, struct cc_ctrl_data *cc_data)
1720{
1721        debug(620, "start");
1722        const uint8_t s_key[16] = { 0x3e, 0x20, 0x15, 0x84, 0x2c, 0x37, 0xce, 0xe3, 0xd6, 0x14, 0x57, 0x3e, 0x3a, 0xab, 0x91, 0xb6 };
1723        AES_KEY aes_ctx;
1724        uint8_t dec[32];
1725        uint8_t *kp;
1726        uint8_t slot;
1727        unsigned int i;
1728
1729        /* check for keyprecursor */
1730        if (!element_valid(cc_data, 12))
1731                return;
1732
1733        /* check for slot */
1734        if (!element_valid(cc_data, 28))
1735                return;
1736
1737        kp = element_get_ptr(cc_data, 12);
1738        element_get_buf(cc_data, &slot, 28);
1739
1740        AES_set_encrypt_key(s_key, 128, &aes_ctx);
1741        for (i = 0; i < 32; i += 16)
1742                AES_ecb_encrypt(&kp[i], &dec[i], &aes_ctx, 1);
1743
1744        for (i = 0; i < 32; i++)
1745        {
1746                dec[i] ^= kp[i];
1747                cc_data->slot->lastKey[i] = dec[i];
1748        }
1749        cc_data->slot->lastParity = slot;
1750
1751        debug(620, "check scrambled=%d", dvbnode->caslot->scrambled);
1752
1753//#ifdef MIPSEL
1754//      descrambler_set_key(dvbnode, 0, slot, dec);
1755//#else
1756#ifndef DREAMBOX
1757        if(dvbnode->caslot->scrambled == 1)
1758#endif
1759                resendKey(dvbnode);
1760//#endif
1761       
1762        /* reset */
1763        element_invalidate(cc_data, 12);
1764        element_invalidate(cc_data, 28);
1765}
1766
1767static int data_get_handle_new(struct dvbdev* dvbnode, struct cc_ctrl_data *cc_data, unsigned int id)
1768{
1769        debug(620, "start");
1770        debug(620, "ID = (%d)", id);
1771
1772        /* handle trigger events */
1773
1774        /* depends on new received items */
1775
1776        switch (id) {
1777        case 8:         /* CICAM_BrandCert */
1778        case 14:        /* DHPM */
1779        case 16:        /* CICAM_DevCert */
1780        case 18:        /* Signature_B */
1781                /* this results in CICAM_ID when cert-chain is verified and ok */
1782                if (check_ci_certificates(cc_data))
1783                        break;
1784                /* generate DHSK & AKH */
1785                check_dh_challenge(cc_data);
1786                break;
1787
1788        case 19:        /* auth_nonce - triggers new dh keychallenge - invalidates DHSK & AKH */
1789                /* generate DHPH & Signature_A */
1790                restart_dh_challenge(cc_data);
1791                break;
1792
1793        case 21:        /* Ns_module - triggers SAC key calculation */
1794                generate_ns_host(cc_data);
1795                generate_key_seed(cc_data);
1796                generate_SAK_SEK(cc_data->sak, cc_data->sek, cc_data->ks_host);
1797                break;
1798
1799        /* SAC data messages */
1800        case 6:         /* CICAM_id */
1801        case 12:                //keyprecursor
1802                check_new_key(dvbnode, cc_data);
1803                break;
1804        case 25:                //uri_message
1805                generate_uri_confirm(cc_data, cc_data->sak);
1806                break;
1807        case 28:                //key register
1808                check_new_key(dvbnode, cc_data);
1809                break;
1810
1811        default:
1812                break;
1813        }
1814
1815        return 0;
1816}
1817
1818static int data_req_handle_new(struct cc_ctrl_data *cc_data, unsigned int id)
1819{
1820        debug(620, "start");
1821        debug(620, "ID = (%d)", id);
1822
1823        switch (id) {
1824        case 22:                /* AKH */
1825        {
1826                uint8_t akh[32], host_id[8];
1827                memset(akh, 0, sizeof(akh));
1828                if (cc_data->akh_index != 5) {
1829                        if (!get_authdata(host_id, cc_data->dhsk, akh, cc_data->slot->connid - 1, cc_data->akh_index++))
1830                                cc_data->akh_index = 5;
1831                        if (!element_set(cc_data, 22, akh, 32))
1832                                printf("cannot set AKH in elements\n");
1833                        if (!element_set(cc_data, 5, host_id, 8))
1834                                printf("cannot set host_id in elements\n");
1835                }
1836        }
1837        default:
1838                break;
1839        }
1840
1841        return 0;
1842}
1843
1844static int data_get_loop(struct dvbdev* dvbnode, struct cc_ctrl_data *cc_data, const unsigned char *data, unsigned int datalen, unsigned int items)
1845{
1846        debug(620, "start");
1847        unsigned int i;
1848        int dt_id, dt_len;
1849        unsigned int pos = 0;
1850
1851        for (i = 0; i < items; i++) {
1852                if (pos + 3 > datalen)
1853                        return 0;
1854
1855                dt_id = data[pos++];
1856                dt_len = data[pos++] << 8;
1857                dt_len |= data[pos++];
1858
1859                if (pos + dt_len > datalen)
1860                        return 0;
1861#if x_debug
1862                printf("set element (%d) ", dt_id);
1863#if y_debug
1864                hexdump(&data[pos], dt_len);
1865#else
1866                printf("\n");
1867#endif
1868#endif
1869                element_set(cc_data, dt_id, &data[pos], dt_len);
1870
1871                data_get_handle_new(dvbnode, cc_data, dt_id);
1872
1873                pos += dt_len;
1874        }
1875
1876        return pos;
1877}
1878
1879static int data_req_loop(struct cc_ctrl_data *cc_data, unsigned char *dest, const unsigned char *data, unsigned int datalen, unsigned int items)
1880{
1881        debug(620, "start");
1882        int dt_id;
1883        unsigned int i;
1884        int pos = 0;
1885        int len;
1886
1887        if (items > datalen)
1888                return -1;
1889
1890        for (i = 0; i < items; i++) {
1891                dt_id = *data++;
1892#if x_debug
1893                printf("req element %d\n", dt_id);
1894#endif
1895                data_req_handle_new(cc_data, dt_id);    /* check if there is any action needed before we answer */
1896                len = element_get_req(cc_data, dest, dt_id);
1897                if (len == 0) {
1898                        printf("cannot get element %d\n", dt_id);
1899                        return -1;
1900                }
1901#if x_debug
1902                printf("element (%d) > ", dt_id);
1903#if y_debug
1904                for (int ic = 0; ic < len; ic++)
1905                        printf("%02x ", dest[ic]);
1906#endif
1907                printf("\n");
1908#endif
1909
1910                pos += len;
1911                dest += len;
1912        }
1913
1914        return pos;
1915}
1916
1917void ci_ccmgr_cc_sac_sync_req(struct dvbdev* dvbnode, int sessionnr, uint8_t *data, unsigned int len)
1918{
1919        debug(620, "start");
1920        uint8_t sync_cnf_tag[3] = { 0x9f, 0x90, 0x10 };
1921        uint8_t dest[64];
1922        unsigned int serial;
1923        int pos = 0;
1924
1925#if y_debug
1926        hexdump(data, len);
1927#endif
1928        serial = UINT32(data, 4);
1929
1930        pos += BYTE32(&dest[pos], serial);
1931        pos += BYTE32(&dest[pos], 0x01000000);
1932
1933        /* status OK */
1934        dest[pos++] = 0;
1935
1936        ci_ccmgr_cc_sac_send(dvbnode, sessionnr, sync_cnf_tag, dest, pos);
1937        dvbnode->caslot->ccmgr_ready = 1;
1938        debug(620, "set ccmgr_ready=%d", dvbnode->caslot->ccmgr_ready);
1939        debug(620, "end");
1940}
1941
1942int checkcerts(void)
1943{
1944        debug(620, "start");
1945        if(status.certchecked == 0)
1946        {
1947#ifndef CERTIN         
1948                if (access(ROOT_CERT, F_OK) == 0 && access(ROOT_CERT, F_OK) == 0 && access(ROOT_CERT, F_OK) == 0)
1949#else
1950                if (access("/mnt/swapextensions/etc/pem/dummy", F_OK) == 0 )
1951#endif
1952                        status.certok = 1;
1953                status.certchecked = 1;
1954        }
1955
1956        return status.certok;
1957}
1958
1959void ci_ccmgr_cc_open_cnf(struct dvbdev* dvbnode, int sessionnr)
1960{
1961        debug(620, "start");
1962        uint8_t tag[3] = { 0x9f, 0x90, 0x02 };
1963        uint8_t bitmap = 0x01;
1964
1965        ci_ccmgr_cc_data_initialize(dvbnode);
1966        sendAPDU(dvbnode, sessionnr, tag, &bitmap, 1);
1967}
1968
1969int ci_ccmgr_cc_data_initialize(struct dvbdev* dvbnode)
1970{
1971        debug(620, "start");
1972        struct cc_ctrl_data *data;
1973        uint8_t buf[32], host_id[8];
1974
1975        if (dvbnode->caslot->private_data) {
1976                fprintf(stderr, "strange private_data not null!\n");
1977                return 0;
1978        }
1979
1980        data = (struct cc_ctrl_data*)calloc(1, sizeof(struct cc_ctrl_data));
1981        if (!data) {
1982                fprintf(stderr, "out of memory\n");
1983                return 0;
1984        }
1985
1986        /* parent */
1987        data->slot = dvbnode->caslot;
1988
1989        /* clear storage of credentials */
1990        element_init(data);
1991
1992        /* set status field - OK */
1993        memset(buf, 0, 1);
1994        if (!element_set(data, 30, buf, 1))
1995                fprintf(stderr, "cannot set status in elements\n");
1996
1997        /* set uri_versions */
1998        memset(buf, 0, 32);
1999        buf[31] = 1;
2000        if (!element_set(data, 29, buf, 32))
2001                fprintf(stderr, "cannot set uri_versions in elements\n");
2002
2003        /* load first AKH */
2004        data->akh_index = 0;
2005        if (!get_authdata(host_id, data->dhsk, buf, dvbnode->caslot->connid - 1, data->akh_index)) {
2006                /* no AKH available */
2007                memset(buf, 0, sizeof(buf));
2008                data->akh_index = 5;    /* last one */
2009        }
2010
2011        if (!element_set(data, 22, buf, 32))
2012                fprintf(stderr, "cannot set AKH in elements\n");
2013
2014        if (!element_set(data, 5, host_id, 8))
2015                fprintf(stderr, "cannot set host_id elements\n");
2016
2017        dvbnode->caslot->private_data = data;
2018
2019//#ifdef MIPSEL
2020//      descrambler_open();
2021//#endif
2022       
2023        return 1;
2024}
2025
2026int ci_ccmgr_cc_data_req(struct dvbdev* dvbnode, int sessionnr, uint8_t *data, unsigned int len)
2027{
2028        debug(620, "start");
2029        struct cc_ctrl_data *cc_data = (struct cc_ctrl_data*)(dvbnode->caslot->private_data);
2030        uint8_t cc_data_cnf_tag[3] = { 0x9f, 0x90, 0x04 };
2031        uint8_t dest[2048 * 2];
2032        int dt_nr;
2033        int id_bitmask;
2034        int answ_len;
2035        unsigned int rp = 0;
2036
2037        if (len < 2)
2038                return 0;
2039
2040        id_bitmask = data[rp++];
2041
2042        /* handle data loop */
2043        dt_nr = data[rp++];
2044        rp += data_get_loop(dvbnode, cc_data, &data[rp], len - rp, dt_nr);
2045
2046        if (len < rp + 1)
2047                return 0;
2048
2049        /* handle req_data loop */
2050        dt_nr = data[rp++];
2051
2052        dest[0] = id_bitmask;
2053        dest[1] = dt_nr;
2054
2055        answ_len = data_req_loop(cc_data, &dest[2], &data[rp], len - rp, dt_nr);
2056        if (answ_len <= 0) {
2057                fprintf(stderr, "cannot req data\n");
2058                return 0;
2059        }
2060
2061        answ_len += 2;
2062
2063        sendAPDU(dvbnode, sessionnr, cc_data_cnf_tag, dest, answ_len);
2064
2065        return 1;
2066}
2067
2068void ci_ccmgr_cc_sync_req(struct dvbdev* dvbnode, int sessionnr)
2069{
2070        debug(620, "start");
2071        uint8_t tag[3] = { 0x9f, 0x90, 0x06 };
2072        uint8_t sync_req_status = 0x00;    /* OK */
2073
2074        sendAPDU(dvbnode, sessionnr, tag, &sync_req_status, 1);
2075}
2076
2077int ci_ccmgr_cc_sac_data_req(struct dvbdev* dvbnode, int sessionnr, uint8_t *data, unsigned int len)
2078{
2079        debug(620, "start");
2080        struct cc_ctrl_data *cc_data = (struct cc_ctrl_data*)(dvbnode->caslot->private_data);
2081        uint8_t data_cnf_tag[3] = { 0x9f, 0x90, 0x08 };
2082        uint8_t dest[2048];
2083        uint8_t tmp[len];
2084        int id_bitmask, dt_nr;
2085        unsigned int serial;
2086        int answ_len;
2087        int pos = 0;
2088        unsigned int rp = 0;
2089
2090        if (len < 10)
2091                return 0;
2092
2093        memcpy(tmp, data, 8);
2094        sac_crypt(&tmp[8], &data[8], len - 8, cc_data->sek, AES_DECRYPT);
2095        data = tmp;
2096#if y_debug
2097        printf("decryted > ");
2098        for (unsigned int i = 0; i < len; i++)
2099                printf("%02x ", data[i]);
2100        printf("\n");
2101#endif
2102        if (!sac_check_auth(data, len, cc_data->sak)) {
2103                fprintf(stderr, "check_auth of message failed\n");
2104                return 0;
2105        }
2106
2107        serial = UINT32(&data[rp], 4);
2108
2109        /* skip serial & header */
2110        rp += 8;
2111
2112        id_bitmask = data[rp++];
2113
2114        /* handle data loop */
2115        dt_nr = data[rp++];
2116        rp += data_get_loop(dvbnode, cc_data, &data[rp], len - rp, dt_nr);
2117
2118        if (len < rp + 1)
2119                return 0;
2120
2121        dt_nr = data[rp++];
2122
2123        /* create answer */
2124        pos += BYTE32(&dest[pos], serial);
2125        pos += BYTE32(&dest[pos], 0x01000000);
2126
2127        dest[pos++] = id_bitmask;
2128        dest[pos++] = dt_nr;    /* dt_nbr */
2129
2130        answ_len = data_req_loop(cc_data, &dest[pos], &data[rp], len - rp, dt_nr);
2131        if (answ_len <= 0) {
2132                fprintf(stderr, "cannot req data\n");
2133                return 0;
2134        }
2135        pos += answ_len;
2136
2137        return ci_ccmgr_cc_sac_send(dvbnode, sessionnr, data_cnf_tag, dest, pos);
2138}
2139
2140int ci_ccmgr_cc_sac_send(struct dvbdev* dvbnode, int sessionnr, uint8_t *tag, uint8_t *data, unsigned int pos)
2141{
2142        debug(620, "start");
2143        debug(620, "Tag: %02X%02X%02X", tag[0], tag[1], tag[2]);
2144        struct cc_ctrl_data *cc_data = (struct cc_ctrl_data*)(dvbnode->caslot->private_data);
2145
2146        if (pos < 8)
2147                return 0;
2148
2149        pos += add_padding(&data[pos], pos - 8, 16);
2150        BYTE16(&data[6], pos - 8);      /* len in header */
2151
2152        pos += sac_gen_auth(&data[pos], data, pos, cc_data->sak);
2153#if y_debug
2154        printf("Data for encrypt > ");
2155        for (unsigned int i = 0; i < pos; i++)
2156                printf("%02x ", data[i]);
2157        printf("\n");
2158#endif
2159        sac_crypt(&data[8], &data[8], pos - 8, cc_data->sek, AES_ENCRYPT);
2160
2161        sendAPDU(dvbnode, sessionnr, tag, data, pos);
2162
2163        return 1;
2164}
2165
2166int sendnullpmt(struct dvbdev* dvbnode, int sessionnr)
2167{
2168        debug(620, "start");
2169        if ((dvbnode->fd > 0) && (dvbnode->caslot->ccmgr_ready))// && (slot->hasCAManager))
2170        {
2171                sendSPDU(dvbnode, 0x90, NULL, 0, sessionnr, NullPMT, 50);
2172        }
2173
2174        return 1;
2175}
2176
2177
2178#endif
Note: See TracBrowser for help on using the repository browser.