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

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