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

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