tsdecrypt reads and decrypts CSA encrypted incoming mpeg transport stream over UDP/RTP using code words obtained from OSCAM or similar CAM server. tsdecrypt communicates with CAM server using cs378x (camd35 over tcp) protocol or newcamd protocol. https://georgi.unixsol.org/programs/tsdecrypt/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

camd-newcamd.c 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. /*
  2. * newcamd protocol
  3. * Most of the code is copied from getstream's newcamd protocol implementation.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2
  7. * as published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  17. */
  18. #define _XOPEN_SOURCE 700 // Needed to pull crypt() from unistd.h
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <unistd.h>
  22. #include <openssl/des.h>
  23. #include "libfuncs/libfuncs.h"
  24. #include "data.h"
  25. #include "util.h"
  26. #include "camd.h"
  27. #define NEWCAMD_PROTO_VER 525
  28. #define NEWCAMD_HDR_LEN 8
  29. #define NEWCAMD_FIRST_CMD_NO 0xe0
  30. typedef enum {
  31. MSG_CLIENT_2_SERVER_LOGIN = NEWCAMD_FIRST_CMD_NO,
  32. MSG_CLIENT_2_SERVER_LOGIN_ACK,
  33. MSG_CLIENT_2_SERVER_LOGIN_NAK,
  34. MSG_CARD_DATA_REQ,
  35. MSG_CARD_DATA,
  36. MSG_SERVER_2_CLIENT_NAME,
  37. MSG_SERVER_2_CLIENT_NAME_ACK,
  38. MSG_SERVER_2_CLIENT_NAME_NAK,
  39. MSG_SERVER_2_CLIENT_LOGIN,
  40. MSG_SERVER_2_CLIENT_LOGIN_ACK,
  41. MSG_SERVER_2_CLIENT_LOGIN_NAK,
  42. MSG_ADMIN,
  43. MSG_ADMIN_ACK,
  44. MSG_ADMIN_LOGIN,
  45. MSG_ADMIN_LOGIN_ACK,
  46. MSG_ADMIN_LOGIN_NAK,
  47. MSG_ADMIN_COMMAND,
  48. MSG_ADMIN_COMMAND_ACK,
  49. MSG_ADMIN_COMMAND_NAK,
  50. MSG_KEEPALIVE = NEWCAMD_FIRST_CMD_NO + 0x1d
  51. } net_msg_type_t;
  52. static void set_odd_parity(uint8_t *key) {
  53. DES_set_odd_parity((DES_cblock *)&key[0]);
  54. DES_set_odd_parity((DES_cblock *)&key[8]);
  55. }
  56. static void des_schedule_key(triple_des_t *td) {
  57. DES_key_sched((DES_cblock *)&td->des_key[0],&td->ks1);
  58. DES_key_sched((DES_cblock *)&td->des_key[8],&td->ks2);
  59. }
  60. static void des_key_spread(triple_des_t *td, uint8_t *normal) {
  61. td->des_key[0] = normal[0] & 0xfe;
  62. td->des_key[1] = ((normal[0] << 7) | (normal[1] >> 1)) & 0xfe;
  63. td->des_key[2] = ((normal[1] << 6) | (normal[2] >> 2)) & 0xfe;
  64. td->des_key[3] = ((normal[2] << 5) | (normal[3] >> 3)) & 0xfe;
  65. td->des_key[4] = ((normal[3] << 4) | (normal[4] >> 4)) & 0xfe;
  66. td->des_key[5] = ((normal[4] << 3) | (normal[5] >> 5)) & 0xfe;
  67. td->des_key[6] = ((normal[5] << 2) | (normal[6] >> 6)) & 0xfe;
  68. td->des_key[7] = normal[6] << 1;
  69. td->des_key[8] = normal[7] & 0xfe;
  70. td->des_key[9] = ((normal[7] << 7) | (normal[8] >> 1)) & 0xfe;
  71. td->des_key[10] = ((normal[8] << 6) | (normal[9] >> 2)) & 0xfe;
  72. td->des_key[11] = ((normal[9] << 5) | (normal[10] >> 3)) & 0xfe;
  73. td->des_key[12] = ((normal[10] << 4) | (normal[11] >> 4)) & 0xfe;
  74. td->des_key[13] = ((normal[11] << 3) | (normal[12] >> 5)) & 0xfe;
  75. td->des_key[14] = ((normal[12] << 2) | (normal[13] >> 6)) & 0xfe;
  76. td->des_key[15] = normal[13] << 1;
  77. set_odd_parity(td->des_key);
  78. };
  79. static uint8_t xor_sum(const uint8_t *mem, int len) {
  80. uint8_t cs = 0;
  81. while (len > 0) {
  82. cs ^= *mem++;
  83. len--;
  84. }
  85. return cs;
  86. }
  87. static int pad_message(uint8_t *data, int len) {
  88. DES_cblock padBytes;
  89. uint8_t noPadBytes = (8 - ((len - 1) % 8)) % 8;
  90. if (len + noPadBytes + 1 >= NEWCAMD_MSG_SIZE - 8)
  91. return -1;
  92. DES_random_key(&padBytes);
  93. memcpy(data + len, padBytes, noPadBytes);
  94. len += noPadBytes;
  95. data[len] = xor_sum(data + 2, len - 2);
  96. return len + 1;
  97. }
  98. static const uint8_t *triple_des_encrypt(triple_des_t *td, uint8_t *data, int len, uint8_t *crypted) {
  99. DES_cblock ivec;
  100. DES_random_key(&ivec);
  101. memcpy(crypted + len, ivec, sizeof(ivec));
  102. DES_ede2_cbc_encrypt(data + 2, crypted + 2, len - 2, &td->ks1, &td->ks2, (DES_cblock *)ivec, DES_ENCRYPT);
  103. return crypted;
  104. }
  105. static void triple_des_decrypt(triple_des_t *td, uint8_t *data, int len) {
  106. if ((len-2) % 8 || (len-2) < 16)
  107. return;
  108. DES_cblock ivec;
  109. len -= sizeof(ivec);
  110. memcpy(ivec, data+len, sizeof(ivec));
  111. DES_ede2_cbc_encrypt(data+2, data+2, len-2, &td->ks1, &td->ks2, (DES_cblock *)ivec, DES_DECRYPT);
  112. }
  113. static void prepare_login_key(struct camd *c, const uint8_t *rkey) {
  114. unsigned int i;
  115. uint8_t tmpkey[14];
  116. for(i = 0; i < sizeof(tmpkey); i++)
  117. tmpkey[i] = rkey[i] ^ c->newcamd.bin_des_key[i];
  118. des_key_spread(&c->newcamd.td_key, tmpkey);
  119. }
  120. static int newcamd_connect(struct camd *c);
  121. static uint8_t newcamd_send_msg(struct camd *c, const uint8_t *data, int data_len, uint16_t service_id, uint8_t useMsgId) {
  122. uint8_t netbuf[NEWCAMD_MSG_SIZE];
  123. if (newcamd_connect(c) < 0)
  124. return -1;
  125. if (data_len < 3 || (data_len + NEWCAMD_HDR_LEN + 4) > NEWCAMD_MSG_SIZE) {
  126. ts_LOGf("ERR | [%s] Bad message size.\n", c->ops.ident);
  127. return 0; // false
  128. }
  129. memset(&netbuf[2], 0, NEWCAMD_HDR_LEN + 2);
  130. memcpy(&netbuf[NEWCAMD_HDR_LEN + 4], data, data_len);
  131. netbuf[NEWCAMD_HDR_LEN + 4 + 1] = (data[1] & 0xF0) | (((data_len - 3) >> 8) & 0x0F);
  132. netbuf[NEWCAMD_HDR_LEN + 4 + 2] = (data_len - 3) & 0xFF;
  133. data_len += 4;
  134. netbuf[4] = service_id >> 8;
  135. netbuf[5] = service_id & 0xFF;
  136. data_len += NEWCAMD_HDR_LEN;
  137. if (useMsgId) {
  138. c->newcamd.msg_id++;
  139. netbuf[2] = c->newcamd.msg_id >> 8;
  140. netbuf[3] = c->newcamd.msg_id & 0xFF;
  141. }
  142. if ((data_len = pad_message(netbuf, data_len)) < 0) {
  143. ts_LOGf("ERR | [%s] Pad_message failed.\n", c->ops.ident);
  144. return 0;
  145. }
  146. if ((data = triple_des_encrypt(&c->newcamd.td_key, netbuf, data_len, netbuf)) == 0) {
  147. ts_LOGf("ERR | [%s] Encrypt failed.\n", c->ops.ident);
  148. return 0;
  149. }
  150. data_len += sizeof(DES_cblock);
  151. netbuf[0] = (data_len - 2) >> 8;
  152. netbuf[1] = (data_len - 2) & 0xFF;
  153. return fdwrite(c->server_fd, (char *)netbuf, data_len);
  154. }
  155. static int newcamd_recv_msg(struct camd *c, uint8_t *data, uint8_t useMsgId) {
  156. uint8_t *netbuf = c->newcamd.buf;
  157. if (fdread(c->server_fd, (char *)netbuf, 2) != 2) {
  158. ts_LOGf("ERR | [%s] Failed to read message.\n", c->ops.ident);
  159. return 0;
  160. }
  161. int mlen = ((netbuf[0] << 8) | netbuf[1]) & 0xFFFF;
  162. if (mlen > NEWCAMD_MSG_SIZE - 2) {
  163. ts_LOGf("ERR | [%s] Buffer overflow [mlen = %d]\n", c->ops.ident, mlen);
  164. return 0;
  165. }
  166. if (fdread(c->server_fd, (char *)netbuf+2, mlen) != mlen) {
  167. ts_LOGf("ERR | [%s] Failed to read message.\n", c->ops.ident);
  168. return 0;
  169. }
  170. mlen += 2;
  171. triple_des_decrypt(&c->newcamd.td_key, netbuf, mlen);
  172. mlen -= sizeof(DES_cblock);
  173. if (xor_sum(netbuf + 2, mlen - 2)) {
  174. ts_LOGf("ERR | [%s] Checksum error.\n", c->ops.ident);
  175. return 0;
  176. }
  177. int retlen = (((netbuf[5 + NEWCAMD_HDR_LEN] << 8) | netbuf[6 + NEWCAMD_HDR_LEN]) & 0x0FFF) + 3;
  178. if (useMsgId) {
  179. uint16_t tmp = ((netbuf[2] << 8) | netbuf[3]) & 0xFFFF;
  180. if (c->newcamd.msg_id != tmp) {
  181. ts_LOGf("ERR | [%s] Bad msg_id %04X != %04X\n", c->ops.ident, c->newcamd.msg_id, tmp);
  182. return -2;
  183. }
  184. }
  185. memmove(data, netbuf + 4 + NEWCAMD_HDR_LEN, retlen);
  186. return retlen;
  187. }
  188. static uint8_t newcamd_send_cmd(struct camd *c, net_msg_type_t cmd) {
  189. uint8_t data[3] = { 0, 0, 0 };
  190. data[0] = cmd;
  191. return newcamd_send_msg(c, data, sizeof(data), 0, 0);
  192. }
  193. static int newcamd_recv_cmd(struct camd *c) {
  194. uint8_t buffer[NEWCAMD_MSG_SIZE];
  195. if (newcamd_recv_msg(c, buffer, 0) != 3)
  196. return -1;
  197. return buffer[0];
  198. }
  199. static void newcamd_init_card_data(struct camd *c, struct newcamd *nc, uint8_t *buffer) {
  200. int i;
  201. char msg_buffer[32];
  202. nc->caid = (buffer[4] << 8) | buffer[5];
  203. for(i = 0; i < 8; i++)
  204. sprintf(&msg_buffer[i*2], "%02X", buffer[6 + i]);
  205. ts_LOGf("CAM | [%s] Card info: CAID 0x%04X Admin=%s srvUA=%s\n",
  206. c->ops.ident, nc->caid, (buffer[3]==1) ? "YES" : "NO", msg_buffer);
  207. memcpy(nc->ua, &buffer[6], 8);
  208. // Parse providers
  209. uint8_t is_ok = 0;
  210. nc->num_of_provs = buffer[14];
  211. for (i = 0; i < nc->num_of_provs; i++) {
  212. if (nc->prov_ident_manual == 0) {
  213. memcpy(nc->provs_ident[i], &buffer[15+11*i], 3);
  214. memcpy(nc->provs_id[i], &buffer[18+11*i], 8);
  215. } else {
  216. if (!memcmp(nc->provs_ident[0], &buffer[15+11*i], 3)) {
  217. is_ok = 1;
  218. memcpy(nc->provs_id[0], &buffer[18+11*i], 8);
  219. } else {
  220. continue;
  221. }
  222. }
  223. uint8_t debug_idx = (nc->prov_ident_manual == 1) ? 0 : i;
  224. ts_LOGf("CAM | [%s] Card info: Provider %d : %02X%02X%02X : %02X%02X%02X%02X%02X%02X%02X%02X\n",
  225. c->ops.ident,
  226. debug_idx,
  227. nc->provs_ident[debug_idx][0], nc->provs_ident[debug_idx][1],
  228. nc->provs_ident[debug_idx][2], nc->provs_id[debug_idx][0],
  229. nc->provs_id[debug_idx][1], nc->provs_id[debug_idx][2],
  230. nc->provs_id[debug_idx][3], nc->provs_id[debug_idx][4],
  231. nc->provs_id[debug_idx][5], nc->provs_id[debug_idx][6],
  232. nc->provs_id[debug_idx][7]);
  233. if (nc->prov_ident_manual == 1 && is_ok == 1) {
  234. nc->num_of_provs = 1;
  235. break;
  236. }
  237. }
  238. }
  239. static int newcamd_login(struct camd *c) {
  240. uint8_t *buffer = c->newcamd.buf;
  241. c->newcamd.caid = 0;
  242. c->newcamd.msg_id = 0;
  243. uint8_t rand_data[14];
  244. if (fdread(c->server_fd, (char *)rand_data, sizeof(rand_data)) != 14) {
  245. ts_LOGf("ERR | [%s] Can't read protocol handshake.\n", c->ops.ident);
  246. return 0;
  247. }
  248. char *crPasswd = crypt(c->pass, "$1$abcdefgh$");
  249. c->newcamd.crypt_passwd = crPasswd;
  250. if (!crPasswd) {
  251. ts_LOGf("ERR | [%s] Can't crypt password.\n", c->ops.ident);
  252. sleep(1);
  253. return -1;
  254. }
  255. const int userLen = strlen(c->user) + 1;
  256. const int passLen = strlen(crPasswd) + 1;
  257. // prepare login message
  258. buffer[0] = MSG_CLIENT_2_SERVER_LOGIN;
  259. buffer[1] = 0;
  260. buffer[2] = userLen + passLen;
  261. memcpy(&buffer[3], c->user, userLen);
  262. memcpy(&buffer[3 + userLen], crPasswd, passLen);
  263. prepare_login_key(c, rand_data);
  264. des_schedule_key(&c->newcamd.td_key);
  265. if (!newcamd_send_msg(c, buffer, buffer[2] + 3, 0, 1) ||
  266. newcamd_recv_cmd(c) != MSG_CLIENT_2_SERVER_LOGIN_ACK)
  267. {
  268. ts_LOGf("ERR | [%s] Login failed. Check user/pass/des-key.\n", c->ops.ident);
  269. sleep(1);
  270. return 0;
  271. }
  272. // Prepare session key
  273. uint8_t tmpkey[14];
  274. memcpy(tmpkey, c->newcamd.bin_des_key, sizeof(tmpkey));
  275. int i;
  276. for(i = 0; i < (passLen - 1); ++i)
  277. tmpkey[i % 14] ^= crPasswd[i];
  278. des_key_spread(&c->newcamd.td_key, tmpkey);
  279. des_schedule_key(&c->newcamd.td_key);
  280. if (!newcamd_send_cmd(c, MSG_CARD_DATA_REQ) || newcamd_recv_msg(c, buffer, 0) <= 0) {
  281. ts_LOGf("ERR | [%s] MSG_CARD_DATA_REQ error.\n", c->ops.ident);
  282. return 0;
  283. }
  284. if (buffer[0] == MSG_CARD_DATA) {
  285. newcamd_init_card_data(c, &c->newcamd, buffer);
  286. } else {
  287. ts_LOGf("ERR | [%s] MSG_CARD_DATA response error.\n", c->ops.ident);
  288. }
  289. return 1;
  290. }
  291. static int newcamd_connect(struct camd *c) {
  292. if (c->server_fd < 0) {
  293. c->server_fd = camd_tcp_connect(c->server_addr, c->server_port);
  294. if (!newcamd_login(c)) {
  295. shutdown_fd(&c->server_fd);
  296. return -1;
  297. }
  298. }
  299. return c->server_fd;
  300. }
  301. static void newcamd_disconnect(struct camd *c) {
  302. shutdown_fd(&c->server_fd);
  303. }
  304. static int newcamd_reconnect(struct camd *c) {
  305. newcamd_disconnect(c);
  306. return newcamd_connect(c);
  307. }
  308. static int newcamd_do_ecm(struct camd *c, struct camd_msg *msg) {
  309. int ret = newcamd_send_msg(c, msg->data, msg->data_len, msg->service_id, 1);
  310. return ret <= 0 ? -1 : ret;
  311. }
  312. static int newcamd_do_emm(struct camd *c, struct camd_msg *msg) {
  313. uint8_t *buf = c->newcamd.buf;
  314. int ret;
  315. ret = newcamd_send_msg(c, msg->data, msg->data_len, msg->service_id, 1);
  316. if (ret <= 0)
  317. return -1;
  318. int data_len = newcamd_recv_msg(c, buf, 1);
  319. if (data_len >= 3) {
  320. if (buf[1] & 0x10)
  321. return 1; // OK
  322. ts_LOGf("ERR | [%s] EMM rejected by card.\n", c->ops.ident);
  323. } else {
  324. ts_LOGf("ERR | [%s] EMM unexpected server response (data_len=%d, buf[1]=0x%02x).\n",
  325. c->ops.ident, data_len, buf[1]);
  326. }
  327. return 0; // Error
  328. }
  329. static int newcamd_get_cw(struct camd *c, uint16_t *ca_id, uint16_t *idx, uint8_t *cw) {
  330. int ret;
  331. int sync_try = 0;
  332. uint8_t *buf = c->newcamd.buf;
  333. while((ret = newcamd_recv_msg(c, buf, 1)) == -2) {
  334. ts_LOGf("ERR | [%s] msg_id sync error. retrying...\n", c->ops.ident);
  335. if (++sync_try > ECM_QUEUE_HARD_LIMIT) {
  336. ts_LOGf("ERR | [%s] Can't sync msg_id after %d tries.\n", c->ops.ident, sync_try);
  337. return -1;
  338. }
  339. }
  340. if (ret != 19) {
  341. if (ret == 3) {
  342. ts_LOGf("ERR | [%s] Card was not able to decode the channel.\n", c->ops.ident);
  343. return 0;
  344. } else {
  345. ts_LOGf("ERR | [%s] Unexpected CAMD server response (code %d).\n", c->ops.ident, ret);
  346. return -1;
  347. }
  348. }
  349. *ca_id = c->newcamd.caid;
  350. *idx = 0; // FIXME
  351. memcpy(cw, c->newcamd.buf + 3, 16);
  352. return 1;
  353. }
  354. void camd_proto_newcamd(struct camd_ops *ops) {
  355. ops->ident = "newcamd";
  356. ops->proto = CAMD_NEWCAMD;
  357. ops->connect = newcamd_connect;
  358. ops->disconnect = newcamd_disconnect;
  359. ops->reconnect = newcamd_reconnect;
  360. ops->do_emm = newcamd_do_emm;
  361. ops->do_ecm = newcamd_do_ecm;
  362. ops->get_cw = newcamd_get_cw;
  363. }