Browse Source

Abstract libdvbcsa calls and move all CSA code in csa.c

Georgi Chorbadzhiyski 12 years ago
parent
commit
a382b55712
8 changed files with 145 additions and 51 deletions
  1. 1
    0
      Makefile
  2. 6
    11
      camd.c
  3. 1
    1
      camd.h
  4. 56
    2
      csa.c
  5. 46
    0
      csa.h
  6. 5
    13
      data.c
  7. 3
    4
      data.h
  8. 27
    20
      process.c

+ 1
- 0
Makefile View File

20
 
20
 
21
 DEFS = -DBUILD_ID=\"$(BUILD_ID)\" \
21
 DEFS = -DBUILD_ID=\"$(BUILD_ID)\" \
22
  -DVERSION=\"$(VERSION)\" -DGIT_VER=\"$(GIT_VER)\"
22
  -DVERSION=\"$(VERSION)\" -DGIT_VER=\"$(GIT_VER)\"
23
+DEFS += -DUSE_LIBDVBCSA=1
23
 
24
 
24
 PREFIX ?= /usr/local
25
 PREFIX ?= /usr/local
25
 
26
 

+ 6
- 11
camd.c View File

24
 #include <netinet/tcp.h>
24
 #include <netinet/tcp.h>
25
 #include <arpa/inet.h>
25
 #include <arpa/inet.h>
26
 
26
 
27
-#include <dvbcsa/dvbcsa.h>
28
-
29
 #include "libfuncs/libfuncs.h"
27
 #include "libfuncs/libfuncs.h"
30
 
28
 
31
 #include "data.h"
29
 #include "data.h"
30
+#include "csa.h"
32
 #include "util.h"
31
 #include "util.h"
33
 #include "camd.h"
32
 #include "camd.h"
34
 #include "notify.h"
33
 #include "notify.h"
62
 	return fd;
61
 	return fd;
63
 }
62
 }
64
 
63
 
65
-void camd_set_cw(struct ts *ts, unsigned char *new_cw, int check_validity) {
64
+void camd_set_cw(struct ts *ts, uint8_t *new_cw, int check_validity) {
66
 	struct camd *c = &ts->camd;
65
 	struct camd *c = &ts->camd;
67
 
66
 
68
 	c->ecm_recv_errors = 0;
67
 	c->ecm_recv_errors = 0;
71
 	c->key->ts = c->key->ts_keyset.tv_sec;
70
 	c->key->ts = c->key->ts_keyset.tv_sec;
72
 	ts->cw_last_warn = c->key->ts;
71
 	ts->cw_last_warn = c->key->ts;
73
 
72
 
74
-	if (!check_validity || memcmp(c->key->cw, invalid_cw, 8) != 0) {
75
-		dvbcsa_key_set   (new_cw, c->key->s_csakey[0]);
76
-		dvbcsa_bs_key_set(new_cw, c->key->bs_csakey[0]);
77
-	}
73
+	if (!check_validity || memcmp(c->key->cw, invalid_cw, 8) != 0)
74
+		csa_set_even_cw(c->key->csakey, new_cw);
78
 
75
 
79
-	if (!check_validity || memcmp(c->key->cw + 8, invalid_cw, 8) != 0) {
80
-		dvbcsa_key_set(new_cw + 8, c->key->s_csakey[1]);
81
-		dvbcsa_bs_key_set(new_cw + 8, c->key->bs_csakey[1]);
82
-	}
76
+	if (!check_validity || memcmp(c->key->cw + 8, invalid_cw, 8) != 0)
77
+		csa_set_odd_cw(c->key->csakey, new_cw + 8);
83
 }
78
 }
84
 
79
 
85
 static int camd_recv_cw(struct ts *ts) {
80
 static int camd_recv_cw(struct ts *ts) {

+ 1
- 1
camd.h View File

25
 struct camd_msg *		camd_msg_alloc		(enum msg_type msg_type, uint16_t ca_id, uint16_t service_id, uint8_t *data, uint8_t data_len);
25
 struct camd_msg *		camd_msg_alloc		(enum msg_type msg_type, uint16_t ca_id, uint16_t service_id, uint8_t *data, uint8_t data_len);
26
 void					camd_msg_free   	(struct camd_msg **pmsg);
26
 void					camd_msg_free   	(struct camd_msg **pmsg);
27
 
27
 
28
-void					camd_set_cw			(struct ts *ts, unsigned char *new_cw, int check_validity);
28
+void					camd_set_cw			(struct ts *ts, uint8_t *new_cw, int check_validity);
29
 
29
 
30
 void					camd_start			(struct ts *ts);
30
 void					camd_start			(struct ts *ts);
31
 void					camd_stop			(struct ts *ts);
31
 void					camd_stop			(struct ts *ts);

+ 56
- 2
csa.c View File

22
 #include <inttypes.h>
22
 #include <inttypes.h>
23
 #include <sys/time.h>
23
 #include <sys/time.h>
24
 
24
 
25
-#include <dvbcsa/dvbcsa.h>
26
-
27
 #include "libfuncs/libfuncs.h"
25
 #include "libfuncs/libfuncs.h"
28
 
26
 
27
+#include "csa.h"
28
+
29
+csakey_t *csa_key_alloc(void) {
30
+	struct csakey *key = calloc(1, sizeof(struct csakey));
31
+	key->s_csakey[0] = dvbcsa_key_alloc();
32
+	key->s_csakey[1] = dvbcsa_key_alloc();
33
+	key->bs_csakey[0] = dvbcsa_bs_key_alloc();
34
+	key->bs_csakey[1] = dvbcsa_bs_key_alloc();
35
+	return (csakey_t *)key;
36
+}
37
+
38
+void csa_key_free(csakey_t **pcsakey) {
39
+	struct csakey *key = *((struct csakey **)pcsakey);
40
+	if (key) {
41
+		dvbcsa_key_free(key->s_csakey[0]);
42
+		dvbcsa_key_free(key->s_csakey[1]);
43
+		dvbcsa_bs_key_free(key->bs_csakey[0]);
44
+		dvbcsa_bs_key_free(key->bs_csakey[1]);
45
+		FREE(*pcsakey);
46
+	}
47
+}
48
+
49
+inline unsigned int csa_get_batch_size(void) {
50
+	if (use_dvbcsa) {
51
+		return dvbcsa_bs_batch_size(); // 32?
52
+	}
53
+	return 0;
54
+}
55
+
56
+inline void csa_set_even_cw(csakey_t *csakey, uint8_t *even_cw) {
57
+	struct csakey *key = (struct csakey *)csakey;
58
+	dvbcsa_key_set(even_cw, key->s_csakey[0]);
59
+	dvbcsa_bs_key_set(even_cw, key->bs_csakey[0]);
60
+}
61
+
62
+inline void csa_set_odd_cw(csakey_t *csakey, uint8_t *odd_cw) {
63
+	struct csakey *key = (struct csakey *)csakey;
64
+	dvbcsa_key_set(odd_cw, key->s_csakey[1]);
65
+	dvbcsa_bs_key_set(odd_cw, key->bs_csakey[1]);
66
+}
67
+
68
+inline void csa_decrypt_single_packet(csakey_t *csakey, uint8_t *payload_start, unsigned int payload_len, unsigned int key_idx) {
69
+	struct csakey *key = (struct csakey *)csakey;
70
+	dvbcsa_decrypt(key->s_csakey[key_idx], payload_start, payload_len);
71
+}
72
+
73
+inline void csa_decrypt_multiple_even(csakey_t *csakey, struct csa_batch *batch) {
74
+	struct csakey *key = (struct csakey *)csakey;
75
+	dvbcsa_bs_decrypt(key->bs_csakey[0], (struct dvbcsa_bs_batch_s *)batch, 184);
76
+}
77
+
78
+inline void csa_decrypt_multiple_odd(csakey_t *csakey, struct csa_batch *batch) {
79
+	struct csakey *key = (struct csakey *)csakey;
80
+	dvbcsa_bs_decrypt(key->bs_csakey[1], (struct dvbcsa_bs_batch_s *)batch, 184);
81
+}
82
+
29
 /* The following routine is taken from benchbitslice in libdvbcsa */
83
 /* The following routine is taken from benchbitslice in libdvbcsa */
30
 void csa_benchmark(void) {
84
 void csa_benchmark(void) {
31
 	struct timeval t0, t1;
85
 	struct timeval t0, t1;

+ 46
- 0
csa.h View File

18
 #ifndef CSA_H
18
 #ifndef CSA_H
19
 #define CSA_H
19
 #define CSA_H
20
 
20
 
21
+// The following *MUST* be the same as struct dvbcsa_bs_batch_s from libdvbcsa
22
+struct csa_batch {
23
+	uint8_t			*data;	// Pointer to payload
24
+	unsigned int	len;	// Payload bytes lenght
25
+};
26
+
27
+#if USE_LIBDVBCSA
28
+#include <dvbcsa/dvbcsa.h>
29
+#define use_dvbcsa 1
30
+#else
31
+#define use_dvbcsa 0
32
+#define dvbcsa_key_t void
33
+#define dvbcsa_bs_key_t void
34
+#define dvbcsa_bs_batch_s csa_batch
35
+static inline dvbcsa_key_t *	dvbcsa_key_alloc(void) { return NULL; }
36
+static inline void				dvbcsa_key_free(dvbcsa_key_t *key) { (void)key; }
37
+static inline void				dvbcsa_key_set(const uint8_t *cw, dvbcsa_key_t *key) { (void)cw; (void)key; }
38
+static inline void				dvbcsa_decrypt(const uint8_t *key, uint8_t *data, unsigned int len) { (void)key; (void)data; (void)len; }
39
+static inline unsigned int		dvbcsa_bs_batch_size(void) { return 0; }
40
+static inline dvbcsa_bs_key_t *	dvbcsa_bs_key_alloc(void) { return NULL; }
41
+static inline void				dvbcsa_bs_key_free(dvbcsa_bs_key_t *key) { (void)key; }
42
+static inline void				dvbcsa_bs_key_set(uint8_t *cw, dvbcsa_bs_key_t *key) { (void)cw; (void)key; }
43
+static inline void				dvbcsa_bs_decrypt(const dvbcsa_bs_key_t *key, const struct dvbcsa_bs_batch_s *pcks, unsigned int maxlen) { (void)key; (void)pcks; (void)maxlen; }
44
+#endif
45
+
46
+#include "data.h"
47
+
48
+struct csakey {
49
+	dvbcsa_key_t		*s_csakey[2];
50
+	dvbcsa_bs_key_t		*bs_csakey[2];
51
+};
52
+
53
+csakey_t *		csa_key_alloc		(void);
54
+void			csa_key_free		(csakey_t **pcsakey);
55
+
56
+unsigned int	csa_get_batch_size	(void);
57
+
58
+void			csa_set_even_cw		(csakey_t *csakey, uint8_t *even_cw);
59
+void			csa_set_odd_cw		(csakey_t *csakey, uint8_t *odd_cw);
60
+
61
+// key_idx 0 == even key
62
+// key_idx 1 == odd key
63
+void			csa_decrypt_single_packet	(csakey_t *csakey, uint8_t *payload, unsigned int payload_len, unsigned int key_idx);
64
+void			csa_decrypt_multiple_even	(csakey_t *csakey, struct csa_batch *batch);
65
+void			csa_decrypt_multiple_odd	(csakey_t *csakey, struct csa_batch *batch);
66
+
21
 void csa_benchmark(void);
67
 void csa_benchmark(void);
22
 
68
 
23
 #endif
69
 #endif

+ 5
- 13
data.c View File

20
 #include <string.h>
20
 #include <string.h>
21
 
21
 
22
 #include "data.h"
22
 #include "data.h"
23
+#include "csa.h"
23
 #include "camd.h"
24
 #include "camd.h"
24
 
25
 
25
 void data_init(struct ts *ts) {
26
 void data_init(struct ts *ts) {
52
 
53
 
53
 	// Key
54
 	// Key
54
 	memset(&ts->key, 0, sizeof(ts->key));
55
 	memset(&ts->key, 0, sizeof(ts->key));
55
-	ts->key.s_csakey[0] = dvbcsa_key_alloc();
56
-	ts->key.s_csakey[1] = dvbcsa_key_alloc();
57
-
58
-	ts->key.bs_csakey[0] = dvbcsa_bs_key_alloc();
59
-	ts->key.bs_csakey[1] = dvbcsa_bs_key_alloc();
60
-
56
+	ts->key.csakey = csa_key_alloc();
61
 	gettimeofday(&ts->key.ts_keyset, NULL);
57
 	gettimeofday(&ts->key.ts_keyset, NULL);
62
 
58
 
63
 	// CAMD
59
 	// CAMD
101
 	ts->output.ttl  = 1;
97
 	ts->output.ttl  = 1;
102
 	ts->output.tos  = -1;
98
 	ts->output.tos  = -1;
103
 
99
 
104
-	ts->decode_buf  = cbuf_init((7 * dvbcsa_bs_batch_size() * 188) * 16, "decode"); // ~658Kb
105
-	ts->write_buf   = cbuf_init((7 * dvbcsa_bs_batch_size() * 188) *  8, "write");  // ~324Kb
100
+	ts->decode_buf  = cbuf_init((7 * csa_get_batch_size() * 188) * 16, "decode"); // ~658Kb
101
+	ts->write_buf   = cbuf_init((7 * csa_get_batch_size() * 188) *  8, "write");  // ~324Kb
106
 
102
 
107
 	ts->input_buffer= list_new("input");
103
 	ts->input_buffer= list_new("input");
108
 
104
 
130
 	ts_privsec_free(&ts->last_ecm);
126
 	ts_privsec_free(&ts->last_ecm);
131
 	ts_privsec_free(&ts->tmp_ecm);
127
 	ts_privsec_free(&ts->tmp_ecm);
132
 
128
 
133
-	dvbcsa_key_free(ts->key.s_csakey[0]);
134
-	dvbcsa_key_free(ts->key.s_csakey[1]);
135
-
136
-	dvbcsa_bs_key_free(ts->key.bs_csakey[0]);
137
-	dvbcsa_bs_key_free(ts->key.bs_csakey[1]);
129
+	csa_key_free(&ts->key.csakey);
138
 
130
 
139
 	cbuf_free(&ts->decode_buf);
131
 	cbuf_free(&ts->decode_buf);
140
 	cbuf_free(&ts->write_buf);
132
 	cbuf_free(&ts->write_buf);

+ 3
- 4
data.h View File

25
 #include <openssl/des.h>
25
 #include <openssl/des.h>
26
 #include <openssl/md5.h>
26
 #include <openssl/md5.h>
27
 
27
 
28
-#include <dvbcsa/dvbcsa.h>
29
-
30
 #include "libfuncs/libfuncs.h"
28
 #include "libfuncs/libfuncs.h"
31
 #include "libtsfuncs/tsfuncs.h"
29
 #include "libtsfuncs/tsfuncs.h"
32
 
30
 
54
 
52
 
55
 #define CODEWORD_LENGTH 16
53
 #define CODEWORD_LENGTH 16
56
 
54
 
55
+typedef void csakey_t;
56
+
57
 struct key {
57
 struct key {
58
 	uint8_t				cw[CODEWORD_LENGTH];
58
 	uint8_t				cw[CODEWORD_LENGTH];
59
+	csakey_t			*csakey;
59
 	int					is_valid_cw;
60
 	int					is_valid_cw;
60
-	struct dvbcsa_key_s	*s_csakey[2];
61
-	struct dvbcsa_bs_key_s	*bs_csakey[2];
62
 	time_t					ts;				// At what time the key is set
61
 	time_t					ts;				// At what time the key is set
63
 	struct timeval			ts_keyset;		// At what time the key is set
62
 	struct timeval			ts_keyset;		// At what time the key is set
64
 };
63
 };

+ 27
- 20
process.c View File

20
 #include <sys/uio.h>
20
 #include <sys/uio.h>
21
 
21
 
22
 #include "data.h"
22
 #include "data.h"
23
+#include "csa.h"
23
 #include "tables.h"
24
 #include "tables.h"
24
 #include "util.h"
25
 #include "util.h"
25
 
26
 
107
 			// scramble_idx 3 == odd key
108
 			// scramble_idx 3 == odd key
108
 			ts_packet_set_not_scrambled(ts_packet);
109
 			ts_packet_set_not_scrambled(ts_packet);
109
 			uint8_t payload_ofs = ts_packet_get_payload_offset(ts_packet);
110
 			uint8_t payload_ofs = ts_packet_get_payload_offset(ts_packet);
110
-			dvbcsa_decrypt(ts->key.s_csakey[scramble_idx - 2], ts_packet + payload_ofs, 188 - payload_ofs);
111
+			csa_decrypt_single_packet(ts->key.csakey, ts_packet + payload_ofs, 188 - payload_ofs, scramble_idx - 2);
111
 		} else {
112
 		} else {
112
 			// Can't decrypt the packet just make it NULL packet
113
 			// Can't decrypt the packet just make it NULL packet
113
 			if (ts->pid_filter)
114
 			if (ts->pid_filter)
118
 
119
 
119
 static void decode_buffer(struct ts *ts, uint8_t *data, int data_len) {
120
 static void decode_buffer(struct ts *ts, uint8_t *data, int data_len) {
120
 	int i;
121
 	int i;
121
-	int batch_sz = dvbcsa_bs_batch_size(); // 32?
122
+	int batch_sz = csa_get_batch_size(); // 32?
122
 	int even_packets = 0;
123
 	int even_packets = 0;
123
 	int odd_packets  = 0;
124
 	int odd_packets  = 0;
124
-	struct dvbcsa_bs_batch_s even_pcks[batch_sz + 1];
125
-	struct dvbcsa_bs_batch_s odd_pcks [batch_sz + 1];
125
+	struct csa_batch even_pcks[batch_sz + 1];
126
+	struct csa_batch odd_pcks [batch_sz + 1];
126
 
127
 
127
 	int scramble_idx_old = 0;
128
 	int scramble_idx_old = 0;
128
 
129
 
136
 				int scramble_idx = ts_packet_get_scrambled(ts_packet);
137
 				int scramble_idx = ts_packet_get_scrambled(ts_packet);
137
 				if (!scramble_idx_old)
138
 				if (!scramble_idx_old)
138
 					scramble_idx_old = scramble_idx;
139
 					scramble_idx_old = scramble_idx;
139
-				uint8_t payload_ofs = ts_packet_get_payload_offset(ts_packet);
140
-				if (scramble_idx == 2) { // scramble_idx 2 == even key
141
-					even_pcks[even_packets].data = ts_packet + payload_ofs;
142
-					even_pcks[even_packets].len  = 188 - payload_ofs;
143
-					even_packets++;
140
+				if (use_dvbcsa) {
141
+					uint8_t payload_ofs = ts_packet_get_payload_offset(ts_packet);
142
+					if (scramble_idx == 2) { // scramble_idx 2 == even key
143
+						even_pcks[even_packets].data = ts_packet + payload_ofs;
144
+						even_pcks[even_packets].len  = 188 - payload_ofs;
145
+						even_packets++;
146
+					}
147
+					if (scramble_idx == 3) { // scramble_idx 3 == odd key
148
+						odd_pcks[odd_packets].data = ts_packet + payload_ofs;
149
+						odd_pcks[odd_packets].len  = 188 - payload_ofs;
150
+						odd_packets++;
151
+					}
152
+					ts_packet_set_not_scrambled(ts_packet);
144
 				}
153
 				}
145
-				if (scramble_idx == 3) { // scramble_idx 3 == odd key
146
-					odd_pcks[odd_packets].data = ts_packet + payload_ofs;
147
-					odd_pcks[odd_packets].len  = 188 - payload_ofs;
148
-					odd_packets++;
149
-				}
150
-				ts_packet_set_not_scrambled(ts_packet);
151
 				if (scramble_idx_old != scramble_idx && !ts->camd.constant_codeword) {
154
 				if (scramble_idx_old != scramble_idx && !ts->camd.constant_codeword) {
152
 					struct timeval tv;
155
 					struct timeval tv;
153
 					gettimeofday(&tv, NULL);
156
 					gettimeofday(&tv, NULL);
166
 
169
 
167
 	// Decode packets
170
 	// Decode packets
168
 	if (even_packets) {
171
 	if (even_packets) {
169
-		even_pcks[even_packets].data = NULL; // Last one...
170
-		dvbcsa_bs_decrypt(ts->key.bs_csakey[0], even_pcks, 184);
172
+		if (use_dvbcsa) {
173
+			even_pcks[even_packets].data = NULL; // Last one...
174
+			csa_decrypt_multiple_even(ts->key.csakey, even_pcks);
175
+		}
171
 	}
176
 	}
172
 	if (odd_packets) {
177
 	if (odd_packets) {
173
-		odd_pcks[odd_packets].data = NULL; // Last one...
174
-		dvbcsa_bs_decrypt(ts->key.bs_csakey[1], odd_pcks, 184);
178
+		if (use_dvbcsa) {
179
+			odd_pcks[odd_packets].data = NULL; // Last one...
180
+			csa_decrypt_multiple_odd(ts->key.csakey, odd_pcks);
181
+		}
175
 	}
182
 	}
176
 
183
 
177
 	// Fill write buffer
184
 	// Fill write buffer
192
 	struct ts *ts = _ts;
199
 	struct ts *ts = _ts;
193
 	uint8_t *data;
200
 	uint8_t *data;
194
 	int data_size;
201
 	int data_size;
195
-	int req_size = 188 * dvbcsa_bs_batch_size();
202
+	int req_size = 188 * csa_get_batch_size();
196
 
203
 
197
 	set_thread_name("tsdec-decode");
204
 	set_thread_name("tsdec-decode");
198
 
205
 

Loading…
Cancel
Save