/device/rockchip/rk30sdk/system/displayd/Hdcp.cpp

https://gitlab.com/brian0218/rk3066_r-box_android4.2.2_sdk · C++ · 344 lines · 278 code · 54 blank · 12 comment · 52 complexity · 07751be88d2ee299f3de5e2313e20c1b MD5 · raw file

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <signal.h>
  4. #include <errno.h>
  5. #include <string.h>
  6. #include <fcntl.h>
  7. #include <sys/ioctl.h>
  8. #define LOG_TAG "HDCP"
  9. #include "cutils/log.h"
  10. #include "Hdcp.h"
  11. #define RKNAND_GET_SN_SECTOR _IOW('d', 3, unsigned int)
  12. #define SN_SECTOR_OP_TAG 0x41444E53 // "SNDA"
  13. #define RKNAND_SYS_STORGAE_DATA_LEN 512
  14. #define ERROR ALOGE
  15. typedef unsigned short uint16;
  16. typedef unsigned int uint32;
  17. typedef unsigned char uint8;
  18. typedef struct tagRKNAND_SYS_STORGAE
  19. {
  20. uint32 tag;
  21. uint32 len;
  22. uint8 data[RKNAND_SYS_STORGAE_DATA_LEN];
  23. }RKNAND_SYS_STORGAE;
  24. void rknand_print_hex_data(uint32 * buf,uint32 len)
  25. {
  26. uint32 i,j,count;
  27. for(i=0;i<len;i+=4)
  28. {
  29. ALOGD("%08x %08x %08x %08x",buf[i],buf[i+1],buf[i+2],buf[i+3]);
  30. }
  31. }
  32. int hdcp_read_key_from_idb(char **buf)
  33. {
  34. uint32 i;
  35. int ret ;
  36. RKNAND_SYS_STORGAE sysData;
  37. ALOGD("hdcp_read_idb start\n");
  38. *buf = NULL;
  39. int sys_fd = open("/dev/rknand_sys_storage",O_RDWR,0);
  40. if(sys_fd < 0){
  41. ALOGE("rknand_sys_storage open fail\n");
  42. return -1;
  43. }
  44. memset(&sysData, 0, sizeof(RKNAND_SYS_STORGAE));
  45. //sn
  46. sysData.tag = SN_SECTOR_OP_TAG;
  47. sysData.len = RKNAND_SYS_STORGAE_DATA_LEN;
  48. ret = ioctl(sys_fd, RKNAND_GET_SN_SECTOR, &sysData);
  49. // rknand_print_hex_data((uint32*)sysData.data,RKNAND_SYS_STORGAE_DATA_LEN);
  50. if(ret){
  51. ALOGE("get sn error\n");
  52. return -1;
  53. }
  54. #if HDCP_KEY_ENCRYPTED
  55. // If HDCP key is encrypted, add decryption at here.
  56. // Decryption Code:
  57. #else
  58. *buf = (char*) malloc(HDCP_KEY_SIZE);
  59. if(*buf) {
  60. memcpy(*buf, sysData.data + HDCP_KEY_IDB_OFFSET, HDCP_KEY_SIZE);
  61. }
  62. else {
  63. ALOGE("malloc error\n");
  64. return -1;
  65. }
  66. #endif
  67. return 0;
  68. }
  69. static int firmware_loading_enable(void)
  70. {
  71. FILE *fd = NULL;
  72. fd = fopen(HDCP_FIRMWARE_LOADING, "w");
  73. if(fd == NULL)
  74. return -1;
  75. fputc('1', fd);
  76. fclose(fd);
  77. return 0;
  78. }
  79. static int firmware_loading_disable(void)
  80. {
  81. FILE *fd = NULL;
  82. fd = fopen(HDCP_FIRMWARE_LOADING, "w");
  83. if(fd == NULL)
  84. return -1;
  85. fputc('0', fd);
  86. fclose(fd);
  87. return 0;
  88. }
  89. static int hdcp_read_key(char **buf, int* size)
  90. {
  91. #ifdef HDCP_KEY_READ_FROM_FILE
  92. FILE *fd = NULL;
  93. fd = fopen(KEY_FILE, "r");
  94. if(fd == NULL) {
  95. *buf = NULL;
  96. *size = 0;
  97. ALOGE("[%s] cant not open file %s\n", __FUNCTION__, KEY_FILE);
  98. return -1;
  99. }
  100. fseek(fd, 0, SEEK_END);
  101. *size = ftell(fd);
  102. *buf = (char*) malloc(*size);
  103. if(*buf) {
  104. fseek(fd, 0, SEEK_SET);
  105. fread(*buf, 1, *size, fd);
  106. }
  107. fclose(fd);
  108. #else
  109. #ifdef HDCP_KEY_READ_FROM_IDB
  110. if(hdcp_read_key_from_idb(buf))
  111. {
  112. *buf = NULL;
  113. *size = 0;
  114. }
  115. else
  116. *size = HDCP_KEY_SIZE;
  117. #endif
  118. #endif
  119. return 0;
  120. }
  121. static int hdcp_read_srm(char **buf, int* size)
  122. {
  123. FILE *fd = NULL;
  124. int invalid_key_size, filesize;
  125. int temp, vrl_length, i;
  126. unsigned char data, generation;
  127. fd = fopen(SRM_FILE, "r");
  128. if(fd == NULL) {
  129. ALOGE("[%s] can not open file %s\n", __FUNCTION__, SRM_FILE);
  130. goto failed;
  131. }
  132. fseek(fd, 0, SEEK_END);
  133. filesize = ftell(fd);
  134. ALOGD("[%s] SRM file size is %d", __FUNCTION__, filesize);
  135. fseek(fd, 0, SEEK_SET);
  136. *buf = (char*) malloc(filesize);
  137. if(*buf == NULL) {
  138. ALOGE("[%s] no enough memory to malloc srm data.\n", __FUNCTION__);
  139. goto failed;
  140. }
  141. memset(*buf, 0, filesize);
  142. temp = 0;
  143. fread(&temp, 1, 2, fd);
  144. if(temp != 0x0080) {
  145. ALOGE("[%s] invalid srm file %s\n", __FUNCTION__, SRM_FILE);
  146. goto invalid;
  147. }
  148. temp = 0;
  149. fread(&temp, 1, 2, fd);
  150. ALOGD("[%s] SRM Version 0x%04x", __FUNCTION__, data);
  151. data = 0;
  152. fread(&generation, 1, 1, fd);
  153. ALOGD("[%s] SRM Generation %d", __FUNCTION__, generation);
  154. //VRL Length
  155. vrl_length = 0;
  156. for(i = 0; i < 3; i++)
  157. {
  158. data = 0;
  159. fread(&data, 1, 1, fd);
  160. vrl_length |= data << ((2 - i) * 8);
  161. }
  162. vrl_length -= 40 + 3;
  163. ALOGD("[%s] SRM 1st block vrl size is %d", __FUNCTION__, vrl_length);
  164. if(!vrl_length) {
  165. ALOGW("[%s] There is no invalid key in SRM file.\n", __FUNCTION__);
  166. goto invalid;
  167. }
  168. invalid_key_size = vrl_length - 1;
  169. data = 0;
  170. fread(&data, 1, 1, fd);
  171. ALOGD("[%s] SRM 1st block invalid key number is %d", __FUNCTION__, data);
  172. if((invalid_key_size/5) != data) {
  173. ALOGE("[%s] invalid key number incorrect.\n", __FUNCTION__);
  174. goto invalid;
  175. }
  176. fread(*buf, 1, invalid_key_size , fd);
  177. fseek(fd, 40, SEEK_CUR);
  178. temp = ftell(fd);
  179. while(temp < filesize)
  180. {
  181. //VRL Length
  182. vrl_length = 0;
  183. for(i = 0; i < 2; i++)
  184. {
  185. data = 0;
  186. fread(&data, 1, 1, fd);
  187. vrl_length |= data << ((1 - i) * 8);
  188. }
  189. if(vrl_length > 42) {
  190. vrl_length -= 42;
  191. data = 0;
  192. fread(&data, 1, 1, fd);
  193. if(data*5 != vrl_length - 1) {
  194. ALOGE("[%s] invalid key number incorrect.\n", __FUNCTION__);
  195. goto invalid;
  196. }
  197. ALOGD("[%s] SRM next block invalid key number is %d", __FUNCTION__, data);
  198. fread(*buf, 1, data * 5, fd);
  199. invalid_key_size += data*5;
  200. fseek(fd, 40, SEEK_CUR);
  201. }
  202. temp = ftell(fd);
  203. }
  204. fclose(fd);
  205. *size = invalid_key_size;
  206. return 0;
  207. invalid:
  208. if(*buf) free(*buf);
  209. fclose(fd);
  210. failed:
  211. *buf = NULL;
  212. *size = 0;
  213. return -1;
  214. }
  215. static int hdcp_write_fireware(char *key, int keysize, char *srm, int srmsize)
  216. {
  217. FILE *fd = NULL;
  218. if(key == NULL || keysize == 0)
  219. return -1;
  220. fd = fopen(HDCP_FIRMWARE_DATA, "w");
  221. if(fd == NULL)
  222. return -1;
  223. fwrite(key, 1, keysize, fd);
  224. if(srmsize && srm) {
  225. fwrite(srm, 1, srmsize, fd);
  226. }
  227. fclose(fd);
  228. return 0;
  229. }
  230. /* Load hdcp key and srm file to kernel. Key and SRM are combined with following mode:
  231. struct firmware {
  232. char key[keysize];
  233. char srm[srmsize];
  234. }
  235. */
  236. static int hdcp_load_firmware(void)
  237. {
  238. char *key = NULL, *srm = NULL;
  239. int keysize = 0, srmsize, rc = -1, i;
  240. ALOGD("%s start\n", __FUNCTION__);
  241. hdcp_read_key(&key, &keysize);
  242. hdcp_read_srm(&srm, &srmsize);
  243. if(keysize) {
  244. rc = firmware_loading_enable();
  245. if(!rc) {
  246. hdcp_write_fireware(key, keysize, srm, srmsize);
  247. rc = firmware_loading_disable();
  248. }
  249. }
  250. if(key) free(key);
  251. if(srm) free(srm);
  252. return rc;
  253. }
  254. static void hdcp_set_trytimes(int times)
  255. {
  256. FILE *fd = NULL;
  257. char buf[5];
  258. fd = fopen(HDCP_TRYTIMES, "w");
  259. if(fd == NULL) return;
  260. memset(buf, 0, 5);
  261. sprintf(buf, "%d", times);
  262. fputs(buf, fd);
  263. fclose(fd);
  264. }
  265. static void hdcp_enable(void)
  266. {
  267. FILE *fd = NULL;
  268. fd = fopen(HDCP_ENABLE, "w");
  269. if(fd == NULL) return;
  270. fputc('1', fd);
  271. fclose(fd);
  272. }
  273. void Hdcp_init() {
  274. ALOGI("HDCP starting");
  275. if (access(HDCP_ENABLE, W_OK) == 0) {
  276. if( (access(HDCP_FIRMWARE_LOADING, W_OK) == 0) &&
  277. (access(HDCP_FIRMWARE_DATA, W_OK) == 0) )
  278. {
  279. if(hdcp_load_firmware() == 0) {
  280. hdcp_set_trytimes(HDCP_AUTH_RETRY_TIMES);
  281. hdcp_enable();
  282. }
  283. }
  284. else
  285. ALOGW("Device not support load HDCP firmware, just exit.\n");
  286. }
  287. else
  288. ALOGW("Device not support HDCP, just exit.\n");
  289. ALOGI("HDCP exiting");
  290. }