Feature #871 ยป libdvbcsa.patch
Makefile | ||
---|---|---|
26 | 26 | |
27 | 27 |
CFLAGS += -Wall -Werror -Wwrite-strings -Wno-deprecated-declarations |
28 | 28 |
CFLAGS += -Wmissing-prototypes |
29 |
LDFLAGS += -lrt -ldl |
|
29 |
LDFLAGS += -lrt -ldl -ldvbcsa
|
|
30 | 30 | |
31 | 31 |
# |
32 | 32 |
# Core |
... | ... | |
102 | 102 |
# cwc |
103 | 103 |
# |
104 | 104 |
SRCS += src/cwc.c \ |
105 |
src/capmt.c \ |
|
106 |
src/ffdecsa/ffdecsa_interface.c \ |
|
107 |
src/ffdecsa/ffdecsa_int.c |
|
105 |
src/capmt.c # \
|
|
106 |
# src/ffdecsa/ffdecsa_interface.c \
|
|
107 |
# src/ffdecsa/ffdecsa_int.c
|
|
108 | 108 | |
109 |
SRCS-${CONFIG_MMX} += src/ffdecsa/ffdecsa_mmx.c |
|
110 |
SRCS-${CONFIG_SSE2} += src/ffdecsa/ffdecsa_sse2.c |
|
109 |
#SRCS-${CONFIG_MMX} += src/ffdecsa/ffdecsa_mmx.c
|
|
110 |
#SRCS-${CONFIG_SSE2} += src/ffdecsa/ffdecsa_sse2.c
|
|
111 | 111 | |
112 |
${BUILDDIR}/src/ffdecsa/ffdecsa_mmx.o : CFLAGS = -mmmx |
|
113 |
${BUILDDIR}/src/ffdecsa/ffdecsa_sse2.o : CFLAGS = -msse2 |
|
112 |
#${BUILDDIR}/src/ffdecsa/ffdecsa_mmx.o : CFLAGS = -mmmx
|
|
113 |
#${BUILDDIR}/src/ffdecsa/ffdecsa_sse2.o : CFLAGS = -msse2
|
|
114 | 114 | |
115 | 115 |
# |
116 | 116 |
# Primary web interface |
src/capmt.c | ||
---|---|---|
39 | 39 |
#include "tcp.h" |
40 | 40 |
#include "psi.h" |
41 | 41 |
#include "tsdemux.h" |
42 |
#include "ffdecsa/FFdecsa.h"
|
|
42 |
#include <dvbcsa/dvbcsa.h>
|
|
43 | 43 |
#include "capmt.h" |
44 | 44 |
#include "notify.h" |
45 | 45 |
#include "subscriptions.h" |
... | ... | |
140 | 140 |
CT_FORBIDDEN |
141 | 141 |
} ct_keystate; |
142 | 142 | |
143 |
/* buffer for keystruct */ |
|
144 |
void *ct_keys; |
|
143 |
/* buffers for keystructs */ |
|
144 |
struct dvbcsa_bs_key_s *ct_key_even; |
|
145 |
struct dvbcsa_bs_key_s *ct_key_odd; |
|
145 | 146 | |
146 | 147 |
/* CSA */ |
147 | 148 |
int ct_cluster_size; |
148 | 149 |
uint8_t *ct_tsbcluster; |
150 |
struct dvbcsa_bs_batch_s *ct_tsbbatch_even; |
|
151 |
struct dvbcsa_bs_batch_s *ct_tsbbatch_odd; |
|
149 | 152 |
int ct_fill; |
153 |
int ct_fill_even; |
|
154 |
int ct_fill_odd; |
|
150 | 155 | |
151 | 156 |
/* current sequence number */ |
152 | 157 |
uint16_t ct_seq; |
... | ... | |
257 | 262 | |
258 | 263 |
LIST_REMOVE(ct, ct_link); |
259 | 264 | |
260 |
free_key_struct(ct->ct_keys); |
|
265 |
dvbcsa_bs_key_free(ct->ct_key_odd); |
|
266 |
dvbcsa_bs_key_free(ct->ct_key_even); |
|
267 |
free(ct->ct_tsbbatch_odd); |
|
268 |
free(ct->ct_tsbbatch_even); |
|
261 | 269 |
free(ct->ct_tsbcluster); |
262 | 270 |
free(ct); |
263 | 271 |
} |
... | ... | |
308 | 316 |
continue; |
309 | 317 | |
310 | 318 |
if (memcmp(even, invalid, 8)) |
311 |
set_even_control_word(ct->ct_keys, even);
|
|
319 |
dvbcsa_bs_key_set(even, ct->ct_key_even);
|
|
312 | 320 |
if (memcmp(odd, invalid, 8)) |
313 |
set_odd_control_word(ct->ct_keys, odd);
|
|
321 |
dvbcsa_bs_key_set(odd, ct->ct_key_odd);
|
|
314 | 322 | |
315 | 323 |
if(ct->ct_keystate != CT_RESOLVED) |
316 | 324 |
tvhlog(LOG_INFO, "capmt", "Obtained key for service \"%s\"",t->s_svcname); |
... | ... | |
558 | 566 |
const uint8_t *tsb) |
559 | 567 |
{ |
560 | 568 |
capmt_service_t *ct = (capmt_service_t *)td; |
561 |
int r, i; |
|
562 |
unsigned char *vec[3]; |
|
569 |
uint8_t *pkt; |
|
570 |
int xc0; |
|
571 |
int ev_od; |
|
572 |
int len; |
|
573 |
int offset; |
|
574 |
int n; |
|
575 |
// FIXME: //int residue; |
|
576 |
int i; |
|
563 | 577 |
uint8_t *t0; |
564 | 578 | |
565 | 579 |
if(ct->ct_keystate == CT_FORBIDDEN) |
... | ... | |
568 | 582 |
if(ct->ct_keystate != CT_RESOLVED) |
569 | 583 |
return -1; |
570 | 584 | |
571 |
memcpy(ct->ct_tsbcluster + ct->ct_fill * 188, tsb, 188); |
|
585 |
pkt = ct->ct_tsbcluster + ct->ct_fill * 188; |
|
586 |
memcpy(pkt, tsb, 188); |
|
572 | 587 |
ct->ct_fill++; |
573 | 588 | |
589 |
do { // handle this packet |
|
590 |
xc0 = pkt[3] & 0xc0; |
|
591 |
if(xc0 == 0x00) { // clear |
|
592 |
break; |
|
593 |
} |
|
594 |
if(xc0 == 0x40) { // reserved |
|
595 |
break; |
|
596 |
} |
|
597 |
if(xc0 == 0x80 || xc0 == 0xc0) { // encrypted |
|
598 |
ev_od = (xc0 & 0x40) >> 6; // 0 even, 1 odd |
|
599 |
pkt[3] &= 0x3f; // consider it decrypted now |
|
600 |
if(pkt[3] & 0x20) { // incomplete packet |
|
601 |
offset = 4 + pkt[4] + 1; |
|
602 |
len = 188 - offset; |
|
603 |
n = len >> 3; |
|
604 |
// FIXME: //residue = len - (n << 3); |
|
605 |
if(n == 0) { // decrypted==encrypted! |
|
606 |
break; // this doesn't need more processing |
|
607 |
} |
|
608 |
} else { |
|
609 |
len = 184; |
|
610 |
offset = 4; |
|
611 |
// FIXME: //n = 23; |
|
612 |
// FIXME: //residue = 0; |
|
613 |
} |
|
614 |
if(ev_od == 0) { |
|
615 |
ct->ct_tsbbatch_even[ct->ct_fill_even].data = pkt + offset; |
|
616 |
ct->ct_tsbbatch_even[ct->ct_fill_even].len = len; |
|
617 |
ct->ct_fill_even++; |
|
618 |
} else { |
|
619 |
ct->ct_tsbbatch_odd[ct->ct_fill_odd].data = pkt + offset; |
|
620 |
ct->ct_tsbbatch_odd[ct->ct_fill_odd].len = len; |
|
621 |
ct->ct_fill_odd++; |
|
622 |
} |
|
623 |
} |
|
624 |
} while(0); |
|
625 | ||
574 | 626 |
if(ct->ct_fill != ct->ct_cluster_size) |
575 | 627 |
return 0; |
576 | 628 | |
577 |
ct->ct_fill = 0; |
|
578 | ||
579 |
vec[0] = ct->ct_tsbcluster; |
|
580 |
vec[1] = ct->ct_tsbcluster + ct->ct_cluster_size * 188; |
|
581 |
vec[2] = NULL; |
|
629 |
if(ct->ct_fill_even) { |
|
630 |
ct->ct_tsbbatch_even[ct->ct_fill_even].data = NULL; |
|
631 |
dvbcsa_bs_decrypt(ct->ct_key_even, ct->ct_tsbbatch_even, 184); |
|
632 |
ct->ct_fill_even = 0; |
|
633 |
} |
|
634 |
if(ct->ct_fill_odd) { |
|
635 |
ct->ct_tsbbatch_odd[ct->ct_fill_odd].data = NULL; |
|
636 |
dvbcsa_bs_decrypt(ct->ct_key_odd, ct->ct_tsbbatch_odd, 184); |
|
637 |
ct->ct_fill_odd = 0; |
|
638 |
} |
|
582 | 639 | |
583 |
while(1) { |
|
584 |
t0 = vec[0]; |
|
585 |
r = decrypt_packets(ct->ct_keys, vec); |
|
586 |
if(r == 0) |
|
587 |
break; |
|
588 |
for(i = 0; i < r; i++) { |
|
640 |
t0 = ct->ct_tsbcluster; |
|
641 |
for(i = 0; i < ct->ct_fill; i++) { |
|
589 | 642 |
ts_recv_packet2(t, t0); |
590 | 643 |
t0 += 188; |
591 | 644 |
} |
592 |
}
|
|
645 |
ct->ct_fill = 0;
|
|
593 | 646 |
return 0; |
594 | 647 |
} |
595 | 648 | |
... | ... | |
617 | 670 |
elementary_stream_t *st; |
618 | 671 | |
619 | 672 |
/* create new capmt service */ |
620 |
ct = calloc(1, sizeof(capmt_service_t)); |
|
621 |
ct->ct_cluster_size = get_suggested_cluster_size(); |
|
622 |
ct->ct_tsbcluster = malloc(ct->ct_cluster_size * 188); |
|
623 |
ct->ct_seq = capmt->capmt_seq++; |
|
673 |
ct = calloc(1, sizeof(capmt_service_t)); |
|
674 |
ct->ct_cluster_size = dvbcsa_bs_batch_size(); |
|
675 |
ct->ct_tsbcluster = malloc(ct->ct_cluster_size * 188); |
|
676 |
ct->ct_tsbbatch_even = malloc((ct->ct_cluster_size + 1) * |
|
677 |
sizeof(struct dvbcsa_bs_batch_s)); |
|
678 |
ct->ct_tsbbatch_odd = malloc((ct->ct_cluster_size + 1) * |
|
679 |
sizeof(struct dvbcsa_bs_batch_s)); |
|
680 |
ct->ct_seq = capmt->capmt_seq++; |
|
624 | 681 | |
625 | 682 |
TAILQ_FOREACH(st, &t->s_components, es_link) { |
626 | 683 |
caid_t *c = LIST_FIRST(&st->es_caids); |
... | ... | |
640 | 697 |
ct->ct_caid_last = -1; |
641 | 698 |
} |
642 | 699 | |
643 |
ct->ct_keys = get_key_struct(); |
|
700 |
ct->ct_key_even = dvbcsa_bs_key_alloc(); |
|
701 |
ct->ct_key_odd = dvbcsa_bs_key_alloc(); |
|
644 | 702 |
ct->ct_capmt = capmt; |
645 | 703 |
ct->ct_service = t; |
646 | 704 |
src/cwc.c | ||
---|---|---|
32 | 32 |
#include "tcp.h" |
33 | 33 |
#include "psi.h" |
34 | 34 |
#include "tsdemux.h" |
35 |
#include "ffdecsa/FFdecsa.h"
|
|
35 |
#include <dvbcsa/dvbcsa.h>
|
|
36 | 36 |
#include "cwc.h" |
37 | 37 |
#include "notify.h" |
38 | 38 |
#include "atomic.h" |
... | ... | |
153 | 153 |
CS_FORBIDDEN |
154 | 154 |
} cs_keystate; |
155 | 155 | |
156 |
void *cs_keys; |
|
156 |
struct dvbcsa_bs_key_s *cs_key_even; |
|
157 |
struct dvbcsa_bs_key_s *cs_key_odd; |
|
157 | 158 | |
158 | 159 | |
159 | 160 |
uint8_t cs_cw[16]; |
... | ... | |
164 | 165 |
*/ |
165 | 166 |
int cs_cluster_size; |
166 | 167 |
uint8_t *cs_tsbcluster; |
168 |
struct dvbcsa_bs_batch_s *cs_tsbbatch_even; |
|
169 |
struct dvbcsa_bs_batch_s *cs_tsbbatch_odd; |
|
167 | 170 |
int cs_fill; |
171 |
int cs_fill_even; |
|
172 |
int cs_fill_odd; |
|
168 | 173 | |
169 | 174 |
LIST_HEAD(, ecm_pid) cs_pids; |
170 | 175 | |
... | ... | |
1661 | 1666 |
ct->cs_pending_cw_update = 0; |
1662 | 1667 |
for(i = 0; i < 8; i++) |
1663 | 1668 |
if(ct->cs_cw[i]) { |
1664 |
set_even_control_word(ct->cs_keys, ct->cs_cw);
|
|
1669 |
dvbcsa_bs_key_set(ct->cs_cw, ct->cs_key_even);
|
|
1665 | 1670 |
break; |
1666 | 1671 |
} |
1667 | 1672 |
|
1668 | 1673 |
for(i = 0; i < 8; i++) |
1669 | 1674 |
if(ct->cs_cw[8 + i]) { |
1670 |
set_odd_control_word(ct->cs_keys, ct->cs_cw + 8);
|
|
1675 |
dvbcsa_bs_key_set(ct->cs_cw + 8, ct->cs_key_odd);
|
|
1671 | 1676 |
break; |
1672 | 1677 |
} |
1673 | 1678 |
} |
... | ... | |
1681 | 1686 |
const uint8_t *tsb) |
1682 | 1687 |
{ |
1683 | 1688 |
cwc_service_t *ct = (cwc_service_t *)td; |
1684 |
int r; |
|
1685 |
unsigned char *vec[3]; |
|
1689 |
uint8_t *pkt; |
|
1690 |
int xc0; |
|
1691 |
int ev_od; |
|
1692 |
int len; |
|
1693 |
int offset; |
|
1694 |
int n; |
|
1695 |
// FIXME: //int residue; |
|
1686 | 1696 | |
1687 | 1697 |
if(ct->cs_keystate == CS_FORBIDDEN) |
1688 | 1698 |
return 1; |
... | ... | |
1693 | 1703 |
if(ct->cs_fill == 0 && ct->cs_pending_cw_update) |
1694 | 1704 |
update_keys(ct); |
1695 | 1705 | |
1696 |
memcpy(ct->cs_tsbcluster + ct->cs_fill * 188, tsb, 188); |
|
1706 |
pkt = ct->cs_tsbcluster + ct->cs_fill * 188; |
|
1707 |
memcpy(pkt, tsb, 188); |
|
1697 | 1708 |
ct->cs_fill++; |
1698 | 1709 | |
1710 |
do { // handle this packet |
|
1711 |
xc0 = pkt[3] & 0xc0; |
|
1712 |
if(xc0 == 0x00) { // clear |
|
1713 |
break; |
|
1714 |
} |
|
1715 |
if(xc0 == 0x40) { // reserved |
|
1716 |
break; |
|
1717 |
} |
|
1718 |
if(xc0 == 0x80 || xc0 == 0xc0) { // encrypted |
|
1719 |
ev_od = (xc0 & 0x40) >> 6; // 0 even, 1 odd |
|
1720 |
pkt[3] &= 0x3f; // consider it decrypted now |
|
1721 |
if(pkt[3] & 0x20) { // incomplete packet |
|
1722 |
offset = 4 + pkt[4] + 1; |
|
1723 |
len = 188 - offset; |
|
1724 |
n = len >> 3; |
|
1725 |
// FIXME: //residue = len - (n << 3); |
|
1726 |
if(n == 0) { // decrypted==encrypted! |
|
1727 |
break; // this doesn't need more processing |
|
1728 |
} |
|
1729 |
} else { |
|
1730 |
len = 184; |
|
1731 |
offset = 4; |
|
1732 |
// FIXME: //n = 23; |
|
1733 |
// FIXME: //residue = 0; |
|
1734 |
} |
|
1735 |
if(ev_od == 0) { |
|
1736 |
ct->cs_tsbbatch_even[ct->cs_fill_even].data = pkt + offset; |
|
1737 |
ct->cs_tsbbatch_even[ct->cs_fill_even].len = len; |
|
1738 |
ct->cs_fill_even++; |
|
1739 |
} else { |
|
1740 |
ct->cs_tsbbatch_odd[ct->cs_fill_odd].data = pkt + offset; |
|
1741 |
ct->cs_tsbbatch_odd[ct->cs_fill_odd].len = len; |
|
1742 |
ct->cs_fill_odd++; |
|
1743 |
} |
|
1744 |
} |
|
1745 |
} while(0); |
|
1746 | ||
1699 | 1747 |
if(ct->cs_fill != ct->cs_cluster_size) |
1700 | 1748 |
return 0; |
1701 | 1749 | |
1702 |
while(1) { |
|
1750 |
if(ct->cs_fill_even) { |
|
1751 |
ct->cs_tsbbatch_even[ct->cs_fill_even].data = NULL; |
|
1752 |
dvbcsa_bs_decrypt(ct->cs_key_even, ct->cs_tsbbatch_even, 184); |
|
1753 |
ct->cs_fill_even = 0; |
|
1754 |
} |
|
1755 |
if(ct->cs_fill_odd) { |
|
1756 |
ct->cs_tsbbatch_odd[ct->cs_fill_odd].data = NULL; |
|
1757 |
dvbcsa_bs_decrypt(ct->cs_key_odd, ct->cs_tsbbatch_odd, 184); |
|
1758 |
ct->cs_fill_odd = 0; |
|
1759 |
} |
|
1703 | 1760 | |
1704 |
vec[0] = ct->cs_tsbcluster; |
|
1705 |
vec[1] = ct->cs_tsbcluster + ct->cs_fill * 188; |
|
1706 |
vec[2] = NULL; |
|
1707 |
|
|
1708 |
r = decrypt_packets(ct->cs_keys, vec); |
|
1709 |
if(r > 0) { |
|
1761 |
{ |
|
1710 | 1762 |
int i; |
1711 | 1763 |
const uint8_t *t0 = ct->cs_tsbcluster; |
1712 | 1764 | |
1713 |
for(i = 0; i < r; i++) {
|
|
1765 |
for(i = 0; i < ct->cs_fill; i++) {
|
|
1714 | 1766 |
ts_recv_packet2(t, t0); |
1715 | 1767 |
t0 += 188; |
1716 | 1768 |
} |
1717 | ||
1718 |
r = ct->cs_fill - r; |
|
1719 |
assert(r >= 0); |
|
1720 | ||
1721 |
if(r > 0) |
|
1722 |
memmove(ct->cs_tsbcluster, t0, r * 188); |
|
1723 |
ct->cs_fill = r; |
|
1724 | ||
1725 |
if(ct->cs_pending_cw_update && r > 0) |
|
1726 |
continue; |
|
1727 |
} else { |
|
1728 |
ct->cs_fill = 0; |
|
1729 |
} |
|
1730 |
break; |
|
1731 | 1769 |
} |
1770 |
ct->cs_fill = 0; |
|
1771 | ||
1732 | 1772 |
if(ct->cs_pending_cw_update) |
1733 | 1773 |
update_keys(ct); |
1734 | 1774 | |
... | ... | |
1757 | 1797 | |
1758 | 1798 |
LIST_REMOVE(ct, cs_link); |
1759 | 1799 | |
1760 |
free_key_struct(ct->cs_keys); |
|
1800 |
dvbcsa_bs_key_free(ct->cs_key_odd); |
|
1801 |
dvbcsa_bs_key_free(ct->cs_key_even); |
|
1802 |
free(ct->cs_tsbbatch_odd); |
|
1803 |
free(ct->cs_tsbbatch_even); |
|
1761 | 1804 |
free(ct->cs_tsbcluster); |
1762 | 1805 |
free(ct); |
1763 | 1806 |
} |
... | ... | |
1802 | 1845 |
continue; |
1803 | 1846 | |
1804 | 1847 |
ct = calloc(1, sizeof(cwc_service_t)); |
1805 |
ct->cs_cluster_size = get_suggested_cluster_size();
|
|
1848 |
ct->cs_cluster_size = dvbcsa_bs_batch_size();
|
|
1806 | 1849 |
ct->cs_tsbcluster = malloc(ct->cs_cluster_size * 188); |
1850 |
ct->cs_tsbbatch_even = malloc((ct->cs_cluster_size + 1) * |
|
1851 |
sizeof(struct dvbcsa_bs_batch_s)); |
|
1852 |
ct->cs_tsbbatch_odd = malloc((ct->cs_cluster_size + 1) * |
|
1853 |
sizeof(struct dvbcsa_bs_batch_s)); |
|
1807 | 1854 | |
1808 |
ct->cs_keys = get_key_struct(); |
|
1855 |
ct->cs_key_even = dvbcsa_bs_key_alloc(); |
|
1856 |
ct->cs_key_odd = dvbcsa_bs_key_alloc(); |
|
1809 | 1857 |
ct->cs_cwc = cwc; |
1810 | 1858 |
ct->cs_service = t; |
1811 | 1859 |
ct->cs_okchannel = -1; |
src/main.c | ||
---|---|---|
57 | 57 |
#include "v4l.h" |
58 | 58 |
#include "trap.h" |
59 | 59 |
#include "settings.h" |
60 |
#include "ffdecsa/FFdecsa.h" |
|
61 | 60 | |
62 | 61 |
int running; |
63 | 62 |
extern const char *htsversion; |
... | ... | |
401 | 400 | |
402 | 401 |
htsp_init(); |
403 | 402 | |
404 |
ffdecsa_init(); |
|
405 |
|
|
406 | 403 |
if(rawts_input != NULL) |
407 | 404 |
rawts_init(rawts_input); |
408 | 405 |