hdcp_qseecom.c 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2015-2022 The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  6. #include <linux/errno.h>
  7. #include <linux/hdcp_qseecom.h>
  8. #include <linux/kernel.h>
  9. #include <linux/sched.h>
  10. #include <linux/slab.h>
  11. #include <linux/types.h>
  12. #include <misc/qseecom_kernel.h>
  13. #include "hdcp_qseecom.h"
  14. #include "hdcp_main.h"
  15. #define HDCP_CMD_STATUS_TO_STR(x) #x
  16. #define hdcp2_app_init_var(x) \
  17. struct hdcp_##x##_req *req_buf = NULL; \
  18. struct hdcp_##x##_rsp *rsp_buf = NULL; \
  19. if (!handle || !handle->qseecom_handle) { \
  20. pr_err("invalid qseecom_handle while processing %s\n", #x); \
  21. rc = -EINVAL; \
  22. goto error; \
  23. } \
  24. req_buf = (struct hdcp_##x##_req *)handle->qseecom_handle->sbuf; \
  25. rsp_buf = (struct hdcp_##x##_rsp *)(handle->qseecom_handle->sbuf + \
  26. QSEECOM_ALIGN(sizeof(struct hdcp_##x##_req))); \
  27. req_buf->commandid = hdcp_cmd_##x
  28. #define hdcp2_app_process_cmd(x) \
  29. ({ \
  30. int rc = qseecom_send_command( \
  31. handle->qseecom_handle, req_buf, \
  32. QSEECOM_ALIGN(sizeof(struct hdcp_##x##_req)), rsp_buf, \
  33. QSEECOM_ALIGN(sizeof(struct hdcp_##x##_rsp))); \
  34. if ((rc < 0) || (rsp_buf->status != HDCP_SUCCESS)) { \
  35. pr_err("qseecom cmd %s failed with err = %d, status = %d:%s\n", \
  36. #x, rc, rsp_buf->status, \
  37. hdcp_cmd_status_to_str(rsp_buf->status)); \
  38. rc = -EINVAL; \
  39. } \
  40. rc; \
  41. })
  42. const char *hdcp_errors[] = {"HDCP_SUCCESS",
  43. "HDCP_FAIL",
  44. "HDCP_BAD_PARAM",
  45. "HDCP_DEVICE_TYPE_UNSUPPORTED",
  46. "HDCP_INVALID_COMMAND",
  47. "HDCP_INVALID_COMMAND_HANDLE",
  48. "HDCP_ERROR_SIZE_IN",
  49. "HDCP_ERROR_SIZE_OUT",
  50. "HDCP_DATA_SIZE_INSUFFICIENT",
  51. "HDCP_UNSUPPORTED_RX_VERSION",
  52. "HDCP_WRONG_RX_CAPAB_MASK",
  53. "HDCP_WRONG_RX_RSVD",
  54. "HDCP_WRONG_RX_HDCP_CAPABLE",
  55. "HDCP_RSA_SIGNATURE_VERIFY_FAILED",
  56. "HDCP_VERIFY_H_PRIME_FAILED",
  57. "HDCP_LC_FAILED",
  58. "HDCP_MESSAGE_TIMEOUT",
  59. "HDCP_COUNTER_ROLL_OVER",
  60. "HDCP_WRONG_RXINFO_RSVD",
  61. "HDCP_RXINFO_MAX_DEVS",
  62. "HDCP_RXINFO_MAX_CASCADE",
  63. "HDCP_WRONG_INITIAL_SEQ_NUM_V",
  64. "HDCP_SEQ_NUM_V_ROLL_OVER",
  65. "HDCP_WRONG_SEQ_NUM_V",
  66. "HDCP_VERIFY_V_FAILED",
  67. "HDCP_RPT_METHOD_INVOKED",
  68. "HDCP_RPT_STRM_LEN_WRONG",
  69. "HDCP_VERIFY_STRM_M_FAILED",
  70. "HDCP_TRANSMITTER_NOT_FOUND",
  71. "HDCP_SESSION_NOT_FOUND",
  72. "HDCP_MAX_SESSION_EXCEEDED",
  73. "HDCP_MAX_CONNECTION_EXCEEDED",
  74. "HDCP_MAX_STREAMS_EXCEEDED",
  75. "HDCP_MAX_DEVICES",
  76. "HDCP_ALLOC_FAILED",
  77. "HDCP_CONNECTION_NOT_FOUND",
  78. "HDCP_HASH_FAILED",
  79. "HDCP_BN_FAILED",
  80. "HDCP_ENCRYPT_KM_FAILED",
  81. "HDCP_DECRYPT_KM_FAILED",
  82. "HDCP_HMAC_FAILED",
  83. "HDCP_GET_RANDOM_FAILED",
  84. "HDCP_INVALID_KEY_HEADER",
  85. "HDCP_INVALID_KEY_LC_HASH",
  86. "HDCP_INVALID_KEY_HASH",
  87. "HDCP_KEY_WRITE_FAILED",
  88. "HDCP_KEY_READ_FAILED",
  89. "HDCP_KEY_DECRYPT_FAILED",
  90. "HDCP_TEST_KEY_ON_SECURE_DEVICE",
  91. "HDCP_KEY_VERSION_UNSUPPORTED",
  92. "HDCP_RXID_NOT_FOUND",
  93. "HDCP_STORAGE_INIT_FAILED",
  94. "HDCP_STORAGE_FILE_OPEN_FAILED",
  95. "HDCP_STORAGE_FILE_READ_FAILED",
  96. "HDCP_STORAGE_FILE_WRITE_FAILED",
  97. "HDCP_STORAGE_ID_UNSUPPORTED",
  98. "HDCP_MUTUAL_EXCLUSIVE_DEVICE_PRESENT",
  99. "HDCP_INVALID_STATE",
  100. "HDCP_CONFIG_READ_FAILED",
  101. "HDCP_OPEN_TZ_SERVICE_FAILED",
  102. "HDCP_HW_CLOCK_OFF",
  103. "HDCP_SET_HW_KEY_FAILED",
  104. "HDCP_CLEAR_HW_KEY_FAILED",
  105. "HDCP_GET_CONTENT_LEVEL_FAILED",
  106. "HDCP_STREAMID_INUSE",
  107. "HDCP_STREAM_NOT_FOUND",
  108. "HDCP_FORCE_ENCRYPTION_FAILED",
  109. "HDCP_STREAMNUMBER_INUSE"};
  110. #define HDCP_TXMTR_SERVICE_ID 0x0001000
  111. #define SERVICE_CREATE_CMD(x) (HDCP_TXMTR_SERVICE_ID | x)
  112. #define HDCP_CMD_STATUS_TO_STR(x) #x
  113. enum {
  114. hdcp_cmd_tx_init = SERVICE_CREATE_CMD(1),
  115. hdcp_cmd_tx_init_v1 = SERVICE_CREATE_CMD(1),
  116. hdcp_cmd_tx_deinit = SERVICE_CREATE_CMD(2),
  117. hdcp_cmd_rcvd_msg = SERVICE_CREATE_CMD(3),
  118. hdcp_cmd_send_timeout = SERVICE_CREATE_CMD(4),
  119. hdcp_cmd_set_hw_key = SERVICE_CREATE_CMD(5),
  120. hdcp_cmd_query_stream_type = SERVICE_CREATE_CMD(6),
  121. hdcp_cmd_init_v1 = SERVICE_CREATE_CMD(11),
  122. hdcp_cmd_init = SERVICE_CREATE_CMD(11),
  123. hdcp_cmd_deinit = SERVICE_CREATE_CMD(12),
  124. hdcp_cmd_version = SERVICE_CREATE_CMD(14),
  125. hdcp_cmd_verify_key = SERVICE_CREATE_CMD(15),
  126. hdcp_cmd_session_init = SERVICE_CREATE_CMD(16),
  127. hdcp_cmd_session_deinit = SERVICE_CREATE_CMD(17),
  128. hdcp_cmd_start_auth = SERVICE_CREATE_CMD(18),
  129. hdcp_cmd_session_open_stream = SERVICE_CREATE_CMD(20),
  130. hdcp_cmd_session_close_stream = SERVICE_CREATE_CMD(21),
  131. hdcp_cmd_force_encryption = SERVICE_CREATE_CMD(22),
  132. };
  133. static struct qseecom_handle *qseecom_handle_g;
  134. static struct qseecom_handle *hdcpsrm_qseecom_handle_g;
  135. static int hdcp2_app_started;
  136. static struct qseecom_handle *hdcp1_qseecom_handle_g;
  137. static int hdcp1_app_started;
  138. static const char *hdcp_cmd_status_to_str(uint32_t err)
  139. {
  140. int len = ARRAY_SIZE(hdcp_errors);
  141. if (err >= 0 && err < len)
  142. return hdcp_errors[err];
  143. else
  144. return "";
  145. }
  146. static int hdcp1_app_load(struct hdcp1_qsee_handle *handle)
  147. {
  148. int rc = 0;
  149. if (!handle) {
  150. pr_err("invalid handle\n");
  151. goto error;
  152. }
  153. if (!hdcp1_qseecom_handle_g) {
  154. rc = qseecom_start_app(&hdcp1_qseecom_handle_g, handle->app_name,
  155. QSEECOM_SBUFF_SIZE);
  156. if (rc) {
  157. pr_err("%s app load failed (%d)\n", handle->app_name, rc);
  158. goto error;
  159. }
  160. }
  161. handle->qseecom_handle = hdcp1_qseecom_handle_g;
  162. hdcp1_app_started++;
  163. rc = qseecom_start_app(&handle->hdcpops_handle, HDCP1OPS_APP_NAME,
  164. QSEECOM_SBUFF_SIZE);
  165. if (rc) {
  166. pr_warn("%s app load failed (%d)\n", HDCP1OPS_APP_NAME, rc);
  167. handle->hdcpops_handle = NULL;
  168. }
  169. handle->hdcp_state |= HDCP_STATE_APP_LOADED;
  170. pr_debug("%s app loaded\n", handle->app_name);
  171. error:
  172. return rc;
  173. }
  174. static void hdcp1_app_unload(struct hdcp1_qsee_handle *handle)
  175. {
  176. int rc = 0;
  177. if (!handle || !handle->qseecom_handle) {
  178. pr_err("invalid handle\n");
  179. return;
  180. }
  181. if (!(handle->hdcp_state & HDCP_STATE_APP_LOADED)) {
  182. pr_warn("%s app not loaded\n", handle->app_name);
  183. return;
  184. }
  185. if (handle->hdcpops_handle) {
  186. /* deallocate the resources for HDCP 1.x ops handle */
  187. rc = qseecom_shutdown_app(&handle->hdcpops_handle);
  188. if (rc)
  189. pr_warn("%s app unload failed (%d)\n", HDCP1OPS_APP_NAME, rc);
  190. }
  191. hdcp1_app_started--;
  192. if (!hdcp1_app_started) {
  193. /* deallocate the resources for qseecom HDCP 1.x handle */
  194. rc = qseecom_shutdown_app(&hdcp1_qseecom_handle_g);
  195. if (rc) {
  196. pr_err("%s app unload failed (%d)\n", handle->app_name, rc);
  197. return;
  198. }
  199. hdcp1_qseecom_handle_g = NULL;
  200. }
  201. handle->qseecom_handle = NULL;
  202. handle->hdcp_state &= ~HDCP_STATE_APP_LOADED;
  203. pr_debug("%s app unloaded\n", handle->app_name);
  204. }
  205. static int hdcp1_set_key(struct hdcp1_qsee_handle *hdcp1_handle, u32 *aksv_msb,
  206. u32 *aksv_lsb)
  207. {
  208. int rc = 0;
  209. struct hdcp1_key_set_req *key_set_req;
  210. struct hdcp1_key_set_rsp *key_set_rsp;
  211. struct qseecom_handle *handle = NULL;
  212. if (aksv_msb == NULL || aksv_lsb == NULL) {
  213. pr_err("invalid aksv\n");
  214. return -EINVAL;
  215. }
  216. if (!hdcp1_handle || !hdcp1_handle->qseecom_handle) {
  217. pr_err("invalid HDCP 1.x handle\n");
  218. return -EINVAL;
  219. }
  220. if (!(hdcp1_handle->hdcp_state & HDCP_STATE_APP_LOADED)) {
  221. pr_err("%s app not loaded\n", hdcp1_handle->app_name);
  222. return -EINVAL;
  223. }
  224. handle = hdcp1_handle->qseecom_handle;
  225. /* set keys and request aksv */
  226. key_set_req = (struct hdcp1_key_set_req *)handle->sbuf;
  227. key_set_req->commandid = HDCP1_SET_KEY;
  228. key_set_rsp = (struct hdcp1_key_set_rsp *)(handle->sbuf +
  229. QSEECOM_ALIGN(sizeof(struct hdcp1_key_set_req)));
  230. rc = qseecom_send_command(
  231. handle, key_set_req, QSEECOM_ALIGN(sizeof(struct hdcp1_key_set_req)),
  232. key_set_rsp, QSEECOM_ALIGN(sizeof(struct hdcp1_key_set_rsp)));
  233. if (rc < 0) {
  234. pr_err("qseecom cmd failed err=%d\n", rc);
  235. return -ENOKEY;
  236. }
  237. rc = key_set_rsp->ret;
  238. if (rc) {
  239. pr_err("set key cmd failed, rsp=%d\n", key_set_rsp->ret);
  240. return -ENOKEY;
  241. }
  242. /* copy bytes into msb and lsb */
  243. *aksv_msb = key_set_rsp->ksv[0] << 24 | key_set_rsp->ksv[1] << 16 |
  244. key_set_rsp->ksv[2] << 8 | key_set_rsp->ksv[3];
  245. *aksv_lsb = key_set_rsp->ksv[4] << 24 | key_set_rsp->ksv[5] << 16 |
  246. key_set_rsp->ksv[6] << 8 | key_set_rsp->ksv[7];
  247. rc = hdcp1_validate_aksv(*aksv_msb, *aksv_lsb);
  248. if (rc) {
  249. pr_err("aksv validation failed (%d)\n", rc);
  250. return rc;
  251. }
  252. return 0;
  253. }
  254. static int hdcp1_verify_key(struct hdcp1_qsee_handle *hdcp1_handle)
  255. {
  256. int rc = 0;
  257. struct hdcp1_key_verify_req *key_verify_req;
  258. struct hdcp1_key_verify_rsp *key_verify_rsp;
  259. struct qseecom_handle *handle = NULL;
  260. if (!hdcp1_handle || !hdcp1_handle->qseecom_handle) {
  261. pr_err("invalid HDCP 1.x handle\n");
  262. return -EINVAL;
  263. }
  264. if (!(hdcp1_handle->hdcp_state & HDCP_STATE_APP_LOADED)) {
  265. pr_err("%s app not loaded\n", hdcp1_handle->app_name);
  266. return -EINVAL;
  267. }
  268. handle = hdcp1_handle->qseecom_handle;
  269. key_verify_req = (struct hdcp1_key_verify_req *)handle->sbuf;
  270. key_verify_req->commandid = HDCP1_KEY_VERIFY;
  271. key_verify_rsp =
  272. (struct hdcp1_key_verify_rsp *)(handle->sbuf +
  273. QSEECOM_ALIGN(sizeof(struct hdcp1_key_verify_req)));
  274. rc = qseecom_send_command(
  275. handle, key_verify_req,
  276. QSEECOM_ALIGN(sizeof(struct hdcp1_key_verify_req)), key_verify_rsp,
  277. QSEECOM_ALIGN(sizeof(struct hdcp1_key_set_rsp)));
  278. if (rc < 0) {
  279. pr_err("command HDCP1_KEY_VERIFY failed (%d)\n", rc);
  280. return -EINVAL;
  281. }
  282. rc = key_verify_rsp->ret;
  283. if (rc == QSEECOMD_ERROR)
  284. qseecomd_down = true;
  285. else
  286. qseecomd_down = false;
  287. if (rc) {
  288. pr_err("key_verify failed, rsp=%d\n", key_verify_rsp->ret);
  289. return -EINVAL;
  290. }
  291. pr_debug("success\n");
  292. return 0;
  293. }
  294. static int hdcp2_app_unload(struct hdcp2_qsee_handle *handle)
  295. {
  296. int rc = 0;
  297. hdcp2_app_init_var(deinit);
  298. hdcp2_app_started--;
  299. if (!hdcp2_app_started) {
  300. hdcp2_app_process_cmd(deinit);
  301. /* deallocate the resources for qseecom HDCPSRM handle */
  302. rc = qseecom_shutdown_app(&handle->hdcpsrm_qseecom_handle);
  303. if (rc)
  304. pr_err("qseecom_shutdown_app failed for HDCPSRM (%d)\n", rc);
  305. hdcpsrm_qseecom_handle_g = NULL;
  306. /* deallocate the resources for qseecom HDCP2P2 handle */
  307. rc = qseecom_shutdown_app(&handle->qseecom_handle);
  308. if (rc) {
  309. pr_err("qseecom_shutdown_app failed for HDCP2P2 (%d)\n", rc);
  310. return rc;
  311. }
  312. qseecom_handle_g = NULL;
  313. }
  314. handle->qseecom_handle = NULL;
  315. handle->hdcpsrm_qseecom_handle = NULL;
  316. handle->hdcp_state &= ~HDCP_STATE_APP_LOADED;
  317. pr_debug("%s app unloaded\n", handle->app_name);
  318. return rc;
  319. error:
  320. if (!hdcp2_app_started)
  321. qseecom_shutdown_app(&handle->hdcpsrm_qseecom_handle);
  322. return rc;
  323. }
  324. static int hdcp2_verify_key(struct hdcp2_qsee_handle *handle)
  325. {
  326. int rc = 0;
  327. hdcp2_app_init_var(verify_key);
  328. if (!(handle->hdcp_state & HDCP_STATE_APP_LOADED)) {
  329. pr_err("%s app not loaded\n", handle->app_name);
  330. rc = -EINVAL;
  331. goto error;
  332. }
  333. rc = hdcp2_app_process_cmd(verify_key);
  334. pr_debug("verify_key = %d\n", rc);
  335. if (rsp_buf->status == QSEECOMD_ERROR)
  336. qseecomd_down = true;
  337. else
  338. qseecomd_down = false;
  339. error:
  340. return rc;
  341. }
  342. static int hdcp2_app_tx_deinit(struct hdcp2_qsee_handle *handle)
  343. {
  344. int rc = 0;
  345. hdcp2_app_init_var(tx_deinit);
  346. if (!(handle->hdcp_state & HDCP_STATE_APP_LOADED)) {
  347. pr_err("%s app not loaded\n", handle->app_name);
  348. rc = -EINVAL;
  349. goto error;
  350. }
  351. if (!(handle->hdcp_state & HDCP_STATE_TXMTR_INIT)) {
  352. pr_err("txmtr not initialized\n");
  353. rc = -EINVAL;
  354. goto error;
  355. }
  356. req_buf->ctxhandle = handle->tz_ctxhandle;
  357. rc = hdcp2_app_process_cmd(tx_deinit);
  358. if (rc)
  359. goto error;
  360. handle->hdcp_state &= ~HDCP_STATE_TXMTR_INIT;
  361. pr_debug("success\n");
  362. error:
  363. return rc;
  364. }
  365. static int hdcp2_app_session_deinit(struct hdcp2_qsee_handle *handle)
  366. {
  367. int rc = 0;
  368. hdcp2_app_init_var(session_deinit);
  369. if (!(handle->hdcp_state & HDCP_STATE_APP_LOADED)) {
  370. pr_err("%s app not loaded\n", handle->app_name);
  371. rc = -EINVAL;
  372. goto error;
  373. }
  374. if (!(handle->hdcp_state & HDCP_STATE_SESSION_INIT)) {
  375. pr_err("session not initialized\n");
  376. rc = -EINVAL;
  377. goto error;
  378. }
  379. req_buf->sessionid = handle->session_id;
  380. rc = hdcp2_app_process_cmd(session_deinit);
  381. if (rc)
  382. goto error;
  383. handle->hdcp_state &= ~HDCP_STATE_SESSION_INIT;
  384. pr_debug("success\n");
  385. error:
  386. return rc;
  387. }
  388. void *hdcp1_init_qseecom(void)
  389. {
  390. struct hdcp1_qsee_handle *handle =
  391. kzalloc(sizeof(struct hdcp1_qsee_handle), GFP_KERNEL);
  392. if (!handle)
  393. goto error;
  394. handle->app_name = HDCP1_APP_NAME;
  395. error:
  396. return handle;
  397. }
  398. bool hdcp1_feature_supported_qseecom(void *data)
  399. {
  400. bool supported = false;
  401. struct hdcp1_qsee_handle *handle = data;
  402. int rc = 0;
  403. int retry = 0;
  404. if (!handle) {
  405. pr_err("invalid handle\n");
  406. goto error;
  407. }
  408. if (handle->feature_supported) {
  409. supported = true;
  410. goto error;
  411. }
  412. rc = hdcp1_app_load(handle);
  413. /* Other than in SUCCESS case, if there is a FAILURE when
  414. * handle is NULL, the hdcp1_app_load will return zero.
  415. * Checking the hdcp_state will ensure that the conditional
  416. * is ONLY true when hdcp1_app_load had no Failures.
  417. */
  418. if (!rc && (handle->hdcp_state & HDCP_STATE_APP_LOADED)) {
  419. do {
  420. if (!hdcp1_verify_key(handle)) {
  421. pr_debug("HDCP 1.x supported\n");
  422. pr_debug("hdcp1_verify_key succeeded on %d retry.\n", retry);
  423. handle->feature_supported = true;
  424. supported = true;
  425. break;
  426. } else if (qseecomd_down) {
  427. pr_debug("Qseecomd is not up. Going to sleep.\n");
  428. msleep(SLEEP_QSEECOMD_WAIT_MS);
  429. retry++;
  430. } else
  431. break;
  432. } while (handle->max_hdcp_key_verify_retries >= retry);
  433. if (qseecomd_down) {
  434. pr_err("hdcp1_verify_key failed after %d retries as Qseecomd is not up.\n",
  435. handle->max_hdcp_key_verify_retries);
  436. }
  437. hdcp1_app_unload(handle);
  438. }
  439. error:
  440. return supported;
  441. }
  442. int hdcp1_set_enc_qseecom(void *data, bool enable)
  443. {
  444. int rc = 0;
  445. struct hdcp1_set_enc_req *set_enc_req;
  446. struct hdcp1_set_enc_rsp *set_enc_rsp;
  447. struct hdcp1_qsee_handle *hdcp1_handle = data;
  448. struct qseecom_handle *handle = NULL;
  449. if (!hdcp1_handle || !hdcp1_handle->qseecom_handle) {
  450. pr_err("invalid HDCP 1.x handle\n");
  451. return -EINVAL;
  452. }
  453. if (!hdcp1_handle->feature_supported) {
  454. pr_err("HDCP 1.x not supported\n");
  455. return -EINVAL;
  456. }
  457. if (!(hdcp1_handle->hdcp_state & HDCP_STATE_APP_LOADED)) {
  458. pr_err("%s app not loaded\n", hdcp1_handle->app_name);
  459. return -EINVAL;
  460. }
  461. handle = hdcp1_handle->qseecom_handle;
  462. /* set keys and request aksv */
  463. set_enc_req = (struct hdcp1_set_enc_req *)handle->sbuf;
  464. set_enc_req->commandid = HDCP1_SET_ENC;
  465. set_enc_req->enable = enable;
  466. set_enc_rsp = (struct hdcp1_set_enc_rsp *)(handle->sbuf +
  467. QSEECOM_ALIGN(sizeof(struct hdcp1_set_enc_req)));
  468. rc = qseecom_send_command(
  469. handle, set_enc_req, QSEECOM_ALIGN(sizeof(struct hdcp1_set_enc_req)),
  470. set_enc_rsp, QSEECOM_ALIGN(sizeof(struct hdcp1_set_enc_rsp)));
  471. if (rc < 0) {
  472. pr_err("qseecom cmd failed err=%d\n", rc);
  473. return -EINVAL;
  474. }
  475. rc = set_enc_rsp->ret;
  476. if (rc) {
  477. pr_err("enc cmd failed, rsp=%d\n", set_enc_rsp->ret);
  478. return -EINVAL;
  479. }
  480. pr_debug("success\n");
  481. return 0;
  482. }
  483. int hdcp1_ops_notify_qseecom(void *data, void *topo, bool is_authenticated)
  484. {
  485. int rc = 0;
  486. struct hdcp1_ops_notify_req *ops_notify_req;
  487. struct hdcp1_ops_notify_rsp *ops_notify_rsp;
  488. struct hdcp1_qsee_handle *hdcp1_handle = data;
  489. struct qseecom_handle *handle = NULL;
  490. struct hdcp1_topology *topology = NULL;
  491. if (!hdcp1_handle || !hdcp1_handle->hdcpops_handle) {
  492. pr_err("invalid HDCP 1.x ops handle\n");
  493. return -EINVAL;
  494. }
  495. if (!hdcp1_handle->feature_supported) {
  496. pr_err("HDCP 1.x not supported\n");
  497. return -EINVAL;
  498. }
  499. if (!(hdcp1_handle->hdcp_state & HDCP_STATE_APP_LOADED)) {
  500. pr_err("%s app not loaded\n", HDCP1OPS_APP_NAME);
  501. return -EINVAL;
  502. }
  503. handle = hdcp1_handle->hdcpops_handle;
  504. topology = (struct hdcp1_topology *)topo;
  505. /* set keys and request aksv */
  506. ops_notify_req = (struct hdcp1_ops_notify_req *)handle->sbuf;
  507. ops_notify_req->commandid = HDCP1_NOTIFY_TOPOLOGY;
  508. ops_notify_req->device_type = DEVICE_TYPE_DP;
  509. ops_notify_req->is_authenticated = is_authenticated;
  510. ops_notify_req->topology.depth = topology->depth;
  511. ops_notify_req->topology.device_count = topology->device_count;
  512. ops_notify_req->topology.max_devices_exceeded =
  513. topology->max_devices_exceeded;
  514. ops_notify_req->topology.max_cascade_exceeded =
  515. topology->max_cascade_exceeded;
  516. /*
  517. * For hdcp1.4 below two nodes are not applicable but as
  518. * TZ ops ta talks with other drivers with same structure
  519. * and want to maintain same interface across hdcp versions,
  520. * we are setting the values to 0.
  521. */
  522. ops_notify_req->topology.hdcp2LegacyDeviceDownstream = 0;
  523. ops_notify_req->topology.hdcp1DeviceDownstream = 0;
  524. memset(ops_notify_req->recv_id_list, 0,
  525. sizeof(uint8_t) * MAX_REC_ID_LIST_SIZE);
  526. ops_notify_rsp =
  527. (struct hdcp1_ops_notify_rsp *)(handle->sbuf +
  528. QSEECOM_ALIGN(sizeof(struct hdcp1_ops_notify_req)));
  529. rc = qseecom_send_command(
  530. handle, ops_notify_req,
  531. QSEECOM_ALIGN(sizeof(struct hdcp1_ops_notify_req)), ops_notify_rsp,
  532. QSEECOM_ALIGN(sizeof(struct hdcp1_ops_notify_rsp)));
  533. rc = ops_notify_rsp->ret;
  534. if (rc < 0) {
  535. pr_warn("Ops notify cmd failed, rsp=%d\n", ops_notify_rsp->ret);
  536. return -EINVAL;
  537. }
  538. pr_debug("ops notify success\n");
  539. return 0;
  540. }
  541. int hdcp1_start_qseecom(void *data, u32 *aksv_msb, u32 *aksv_lsb)
  542. {
  543. int rc = 0;
  544. struct hdcp1_qsee_handle *handle = data;
  545. if (!aksv_msb || !aksv_lsb) {
  546. pr_err("invalid aksv output buffer\n");
  547. rc = -EINVAL;
  548. goto error;
  549. }
  550. if (!handle) {
  551. pr_err("invalid handle\n");
  552. rc = -EINVAL;
  553. goto error;
  554. }
  555. if (!handle->feature_supported) {
  556. pr_err("feature not supported\n");
  557. rc = -EINVAL;
  558. goto error;
  559. }
  560. if (handle->hdcp_state & HDCP_STATE_APP_LOADED) {
  561. pr_debug("%s app already loaded\n", handle->app_name);
  562. goto error;
  563. }
  564. rc = hdcp1_app_load(handle);
  565. if (rc)
  566. goto error;
  567. rc = hdcp1_set_key(handle, aksv_msb, aksv_lsb);
  568. if (rc)
  569. goto key_error;
  570. pr_debug("success\n");
  571. return rc;
  572. key_error:
  573. hdcp1_app_unload(handle);
  574. error:
  575. return rc;
  576. }
  577. void hdcp1_stop_qseecom(void *data)
  578. {
  579. struct hdcp1_qsee_handle *hdcp1_handle = data;
  580. if (!hdcp1_handle || !hdcp1_handle->qseecom_handle ||
  581. !hdcp1_handle->hdcpops_handle) {
  582. pr_err("invalid handle\n");
  583. return;
  584. }
  585. if (!(hdcp1_handle->hdcp_state & HDCP_STATE_APP_LOADED)) {
  586. pr_debug("%s app not loaded\n", hdcp1_handle->app_name);
  587. return;
  588. }
  589. hdcp1_app_unload(hdcp1_handle);
  590. }
  591. static int hdcp2_app_init_legacy(struct hdcp2_qsee_handle *handle)
  592. {
  593. int rc = 0;
  594. hdcp2_app_init_var(init_v1);
  595. if (!handle->legacy_app) {
  596. pr_err("wrong init function\n");
  597. rc = -EINVAL;
  598. goto error;
  599. }
  600. if (handle->hdcp_state & HDCP_STATE_APP_LOADED) {
  601. pr_err("library already loaded\n");
  602. goto error;
  603. }
  604. rc = hdcp2_app_process_cmd(init_v1);
  605. if (rc)
  606. goto error;
  607. pr_debug("success\n");
  608. error:
  609. return rc;
  610. }
  611. static int hdcp2_app_tx_init_legacy(struct hdcp2_qsee_handle *handle)
  612. {
  613. int rc = 0;
  614. hdcp2_app_init_var(tx_init_v1);
  615. if (!(handle->hdcp_state & HDCP_STATE_APP_LOADED)) {
  616. pr_err("app not loaded\n");
  617. rc = -EINVAL;
  618. goto error;
  619. }
  620. if (handle->hdcp_state & HDCP_STATE_TXMTR_INIT) {
  621. pr_err("txmtr already initialized\n");
  622. goto error;
  623. }
  624. rc = hdcp2_app_process_cmd(tx_init_v1);
  625. if (rc)
  626. goto error;
  627. handle->app_data.response.data = rsp_buf->message;
  628. handle->app_data.response.length = rsp_buf->msglen;
  629. handle->app_data.timeout = rsp_buf->timeout;
  630. handle->tz_ctxhandle = rsp_buf->ctxhandle;
  631. handle->hdcp_state |= HDCP_STATE_TXMTR_INIT;
  632. pr_debug("success\n");
  633. error:
  634. return rc;
  635. }
  636. static int hdcp2_app_init(struct hdcp2_qsee_handle *handle)
  637. {
  638. int rc = 0;
  639. uint32_t app_minor_version = 0;
  640. hdcp2_app_init_var(init);
  641. if (handle->legacy_app) {
  642. pr_err("wrong init function\n");
  643. rc = -EINVAL;
  644. goto error;
  645. }
  646. if (handle->hdcp_state & HDCP_STATE_APP_LOADED) {
  647. pr_err("library already loaded\n");
  648. goto error;
  649. }
  650. req_buf->clientversion = HDCP_CLIENT_MAKE_VERSION(
  651. HDCP_CLIENT_MAJOR_VERSION, HDCP_CLIENT_MINOR_VERSION,
  652. HDCP_CLIENT_PATCH_VERSION);
  653. rc = hdcp2_app_process_cmd(init);
  654. if (rc)
  655. goto error;
  656. app_minor_version = HCDP_TXMTR_GET_MINOR_VERSION(rsp_buf->appversion);
  657. if (app_minor_version != HDCP_CLIENT_MINOR_VERSION) {
  658. pr_err("client-app minor version mismatch app(%d), client(%d)\n",
  659. app_minor_version, HDCP_CLIENT_MINOR_VERSION);
  660. rc = -1;
  661. goto error;
  662. }
  663. pr_debug("success\n");
  664. pr_debug("client version major(%d), minor(%d), patch(%d)\n",
  665. HDCP_CLIENT_MAJOR_VERSION, HDCP_CLIENT_MINOR_VERSION,
  666. HDCP_CLIENT_PATCH_VERSION);
  667. pr_debug("app version major(%d), minor(%d), patch(%d)\n",
  668. HCDP_TXMTR_GET_MAJOR_VERSION(rsp_buf->appversion),
  669. HCDP_TXMTR_GET_MINOR_VERSION(rsp_buf->appversion),
  670. HCDP_TXMTR_GET_PATCH_VERSION(rsp_buf->appversion));
  671. error:
  672. return rc;
  673. }
  674. static int hdcp2_app_tx_init(struct hdcp2_qsee_handle *handle)
  675. {
  676. int rc = 0;
  677. hdcp2_app_init_var(tx_init);
  678. if (!(handle->hdcp_state & HDCP_STATE_SESSION_INIT)) {
  679. pr_err("session not initialized\n");
  680. rc = -EINVAL;
  681. goto error;
  682. }
  683. if (handle->hdcp_state & HDCP_STATE_TXMTR_INIT) {
  684. pr_err("txmtr already initialized\n");
  685. goto error;
  686. }
  687. req_buf->sessionid = handle->session_id;
  688. rc = hdcp2_app_process_cmd(tx_init);
  689. if (rc)
  690. goto error;
  691. handle->tz_ctxhandle = rsp_buf->ctxhandle;
  692. handle->hdcp_state |= HDCP_STATE_TXMTR_INIT;
  693. pr_debug("success\n");
  694. error:
  695. return rc;
  696. }
  697. static int hdcp_get_version(struct hdcp2_qsee_handle *handle)
  698. {
  699. int rc = 0;
  700. uint32_t app_major_version = 0;
  701. hdcp2_app_init_var(version);
  702. if (handle->hdcp_state & HDCP_STATE_APP_LOADED) {
  703. pr_err("library already loaded\n");
  704. goto error;
  705. }
  706. rc = hdcp2_app_process_cmd(version);
  707. if (rc)
  708. goto error;
  709. app_major_version = HCDP_TXMTR_GET_MAJOR_VERSION(rsp_buf->appversion);
  710. pr_debug("hdp2p2 app major version %d, app version %d\n", app_major_version,
  711. rsp_buf->appversion);
  712. if (app_major_version == 1)
  713. handle->legacy_app = true;
  714. error:
  715. return rc;
  716. }
  717. static int hdcp2_app_load(struct hdcp2_qsee_handle *handle)
  718. {
  719. int rc = 0;
  720. if (!handle) {
  721. pr_err("invalid input\n");
  722. rc = -EINVAL;
  723. goto error;
  724. }
  725. if (handle->hdcp_state & HDCP_STATE_APP_LOADED) {
  726. pr_err("%s app already loaded\n", handle->app_name);
  727. goto error;
  728. }
  729. if (!qseecom_handle_g) {
  730. rc = qseecom_start_app(&qseecom_handle_g,
  731. handle->app_name, QSEECOM_SBUFF_SIZE);
  732. if (rc) {
  733. pr_err("qseecom_start_app failed for HDCP2P2 (%d)\n", rc);
  734. goto error;
  735. }
  736. }
  737. handle->qseecom_handle = qseecom_handle_g;
  738. if (!hdcpsrm_qseecom_handle_g) {
  739. rc = qseecom_start_app(&hdcpsrm_qseecom_handle_g,
  740. HDCPSRM_APP_NAME, QSEECOM_SBUFF_SIZE);
  741. if (rc) {
  742. pr_err("qseecom_start_app failed for HDCPSRM (%d)\n", rc);
  743. goto hdcpsrm_error;
  744. }
  745. }
  746. handle->hdcpsrm_qseecom_handle = hdcpsrm_qseecom_handle_g;
  747. pr_debug("qseecom_start_app success\n");
  748. rc = hdcp_get_version(handle);
  749. if (rc) {
  750. pr_err("library get version failed\n");
  751. goto get_version_error;
  752. }
  753. if (handle->legacy_app) {
  754. handle->app_init = hdcp2_app_init_legacy;
  755. handle->tx_init = hdcp2_app_tx_init_legacy;
  756. } else {
  757. handle->app_init = hdcp2_app_init;
  758. handle->tx_init = hdcp2_app_tx_init;
  759. }
  760. if (!hdcp2_app_started) {
  761. rc = handle->app_init(handle);
  762. if (rc) {
  763. pr_err("app init failed\n");
  764. goto get_version_error;
  765. }
  766. }
  767. hdcp2_app_started++;
  768. handle->hdcp_state |= HDCP_STATE_APP_LOADED;
  769. return rc;
  770. get_version_error:
  771. if (!hdcp2_app_started) {
  772. qseecom_shutdown_app(&hdcpsrm_qseecom_handle_g);
  773. hdcpsrm_qseecom_handle_g = NULL;
  774. }
  775. handle->hdcpsrm_qseecom_handle = NULL;
  776. hdcpsrm_error:
  777. if (!hdcp2_app_started) {
  778. qseecom_shutdown_app(&qseecom_handle_g);
  779. qseecom_handle_g = NULL;
  780. }
  781. handle->qseecom_handle = NULL;
  782. error:
  783. return rc;
  784. }
  785. static int hdcp2_app_session_init(struct hdcp2_qsee_handle *handle)
  786. {
  787. int rc = 0;
  788. hdcp2_app_init_var(session_init);
  789. if (!handle->qseecom_handle || !handle->qseecom_handle->sbuf) {
  790. pr_err("invalid handle\n");
  791. rc = -EINVAL;
  792. goto error;
  793. }
  794. if (!(handle->hdcp_state & HDCP_STATE_APP_LOADED)) {
  795. pr_err("%s app not loaded\n", handle->app_name);
  796. rc = -EINVAL;
  797. goto error;
  798. }
  799. if (handle->hdcp_state & HDCP_STATE_SESSION_INIT) {
  800. pr_err("session already initialized\n");
  801. goto error;
  802. }
  803. req_buf->deviceid = handle->device_type;
  804. rc = hdcp2_app_process_cmd(session_init);
  805. if (rc)
  806. goto error;
  807. pr_debug("session id %d\n", rsp_buf->sessionid);
  808. handle->session_id = rsp_buf->sessionid;
  809. handle->hdcp_state |= HDCP_STATE_SESSION_INIT;
  810. pr_debug("success\n");
  811. error:
  812. return rc;
  813. }
  814. void *hdcp2_init_qseecom(u32 device_type)
  815. {
  816. struct hdcp2_qsee_handle *handle =
  817. kzalloc(sizeof(struct hdcp2_qsee_handle), GFP_KERNEL);
  818. if (!handle)
  819. goto error;
  820. handle->device_type = device_type;
  821. handle->app_name = HDCP2P2_APP_NAME;
  822. handle->res_buf = kmalloc(QSEECOM_SBUFF_SIZE, GFP_KERNEL);
  823. if (!handle->res_buf) {
  824. kfree_sensitive(handle);
  825. return NULL;
  826. }
  827. handle->req_buf = kmalloc(QSEECOM_SBUFF_SIZE, GFP_KERNEL);
  828. if (!handle->req_buf) {
  829. kfree_sensitive(handle->res_buf);
  830. kfree_sensitive(handle);
  831. return NULL;
  832. }
  833. handle->app_data.request.data = handle->req_buf;
  834. handle->app_data.response.data = handle->res_buf;
  835. error:
  836. return handle;
  837. }
  838. void hdcp2_deinit_qseecom(void *ctx)
  839. {
  840. struct hdcp2_qsee_handle *handle = NULL;
  841. int rc = 0;
  842. handle = ctx;
  843. if (!handle) {
  844. pr_err("invalid handle\n");
  845. rc = -EINVAL;
  846. goto error;
  847. }
  848. kfree_sensitive(handle->res_buf);
  849. kfree_sensitive(handle->req_buf);
  850. error:
  851. kfree_sensitive(ctx);
  852. }
  853. int hdcp2_app_start_qseecom(void *ctx, uint32_t req_len)
  854. {
  855. struct hdcp2_qsee_handle *handle = NULL;
  856. int rc = 0;
  857. handle = ctx;
  858. if (!handle) {
  859. pr_err("invalid handle\n");
  860. rc = -EINVAL;
  861. goto error;
  862. }
  863. handle->app_data.request.length = req_len;
  864. rc = hdcp2_app_load(handle);
  865. if (rc)
  866. goto error;
  867. if (!handle->legacy_app) {
  868. rc = hdcp2_app_session_init(handle);
  869. if (rc)
  870. goto error;
  871. }
  872. if (handle->tx_init == NULL) {
  873. pr_err("invalid txmtr init function pointer\n");
  874. rc = -EINVAL;
  875. goto error;
  876. }
  877. rc = handle->tx_init(handle);
  878. error:
  879. return rc;
  880. }
  881. int hdcp2_app_start_auth_qseecom(void *ctx, uint32_t req_len)
  882. {
  883. int rc = 0;
  884. struct hdcp2_qsee_handle *handle = (struct hdcp2_qsee_handle *)ctx;
  885. hdcp2_app_init_var(start_auth);
  886. if (!handle) {
  887. pr_err("invalid handle\n");
  888. rc = -EINVAL;
  889. goto error;
  890. }
  891. handle->app_data.request.length = req_len;
  892. if (!(handle->hdcp_state & HDCP_STATE_SESSION_INIT)) {
  893. pr_err("session not initialized\n");
  894. rc = -EINVAL;
  895. goto error;
  896. }
  897. if (!(handle->hdcp_state & HDCP_STATE_TXMTR_INIT)) {
  898. pr_err("txmtr not initialized\n");
  899. rc = -EINVAL;
  900. goto error;
  901. }
  902. req_buf->ctxHandle = handle->tz_ctxhandle;
  903. rc = hdcp2_app_process_cmd(start_auth);
  904. if (rc)
  905. goto error;
  906. memcpy(handle->res_buf, rsp_buf->message, rsp_buf->msglen);
  907. handle->app_data.response.length = rsp_buf->msglen;
  908. handle->app_data.timeout = rsp_buf->timeout;
  909. handle->app_data.repeater_flag = false;
  910. handle->tz_ctxhandle = rsp_buf->ctxhandle;
  911. pr_debug("success\n");
  912. error:
  913. return rc;
  914. }
  915. int hdcp2_app_process_msg_qseecom(void *ctx, uint32_t req_len)
  916. {
  917. int rc = 0;
  918. struct hdcp2_qsee_handle *handle = (struct hdcp2_qsee_handle *)ctx;
  919. hdcp2_app_init_var(rcvd_msg);
  920. if (!handle) {
  921. pr_err("invalid handle\n");
  922. rc = -EINVAL;
  923. goto error;
  924. }
  925. handle->app_data.request.length = req_len;
  926. if (!handle->app_data.request.data) {
  927. pr_err("invalid request buffer\n");
  928. rc = -EINVAL;
  929. goto error;
  930. }
  931. req_buf->msglen = handle->app_data.request.length;
  932. req_buf->ctxhandle = handle->tz_ctxhandle;
  933. memcpy(req_buf->msg, handle->req_buf, handle->app_data.request.length);
  934. rc = hdcp2_app_process_cmd(rcvd_msg);
  935. if (rc)
  936. goto error;
  937. /* check if it's a repeater */
  938. if (rsp_buf->flag == HDCP_TXMTR_SUBSTATE_WAITING_FOR_RECIEVERID_LIST)
  939. handle->app_data.repeater_flag = true;
  940. memcpy(handle->res_buf, rsp_buf->msg, rsp_buf->msglen);
  941. handle->app_data.response.length = rsp_buf->msglen;
  942. handle->app_data.timeout = rsp_buf->timeout;
  943. error:
  944. return rc;
  945. }
  946. int hdcp2_app_timeout_qseecom(void *ctx, uint32_t req_len)
  947. {
  948. int rc = 0;
  949. struct hdcp2_qsee_handle *handle = (struct hdcp2_qsee_handle *)ctx;
  950. hdcp2_app_init_var(send_timeout);
  951. if (!handle) {
  952. pr_err("invalid handle\n");
  953. rc = -EINVAL;
  954. goto error;
  955. }
  956. handle->app_data.request.length = req_len;
  957. rc = hdcp2_app_process_cmd(send_timeout);
  958. if (rc)
  959. goto error;
  960. memcpy(handle->res_buf, rsp_buf->message, rsp_buf->msglen);
  961. handle->app_data.response.length = rsp_buf->msglen;
  962. handle->app_data.timeout = rsp_buf->timeout;
  963. error:
  964. return rc;
  965. }
  966. int hdcp2_app_enable_encryption_qseecom(void *ctx, uint32_t req_len)
  967. {
  968. int rc = 0;
  969. struct hdcp2_qsee_handle *handle = (struct hdcp2_qsee_handle *)ctx;
  970. hdcp2_app_init_var(set_hw_key);
  971. if (!handle) {
  972. pr_err("Invalid handle\n");
  973. rc = -EINVAL;
  974. goto error;
  975. }
  976. handle->app_data.request.length = req_len;
  977. /*
  978. * wait at least 200ms before enabling encryption
  979. * as per hdcp2p2 specifications.
  980. */
  981. msleep(SLEEP_SET_HW_KEY_MS);
  982. req_buf->ctxhandle = handle->tz_ctxhandle;
  983. rc = hdcp2_app_process_cmd(set_hw_key);
  984. if (rc)
  985. goto error;
  986. handle->hdcp_state |= HDCP_STATE_AUTHENTICATED;
  987. error:
  988. return rc;
  989. }
  990. int hdcp2_app_query_stream_qseecom(void *ctx, uint32_t req_len)
  991. {
  992. int rc = 0;
  993. struct hdcp2_qsee_handle *handle = (struct hdcp2_qsee_handle *)ctx;
  994. hdcp2_app_init_var(query_stream_type);
  995. if (!handle) {
  996. pr_err("Invalid handle\n");
  997. rc = -EINVAL;
  998. goto error;
  999. }
  1000. handle->app_data.request.length = req_len;
  1001. req_buf->ctxhandle = handle->tz_ctxhandle;
  1002. rc = hdcp2_app_process_cmd(query_stream_type);
  1003. if (rc)
  1004. goto error;
  1005. memcpy(handle->res_buf, rsp_buf->msg, rsp_buf->msglen);
  1006. handle->app_data.response.length = rsp_buf->msglen;
  1007. handle->app_data.timeout = rsp_buf->timeout;
  1008. error:
  1009. return rc;
  1010. }
  1011. int hdcp2_app_stop_qseecom(void *ctx)
  1012. {
  1013. int rc = 0;
  1014. struct hdcp2_qsee_handle *handle = (struct hdcp2_qsee_handle *)ctx;
  1015. if (!handle) {
  1016. pr_err("Invalid handle\n");
  1017. rc = -EINVAL;
  1018. goto error;
  1019. }
  1020. rc = hdcp2_app_tx_deinit(handle);
  1021. if (rc)
  1022. goto error;
  1023. if (!handle->legacy_app) {
  1024. rc = hdcp2_app_session_deinit(handle);
  1025. if (rc)
  1026. goto error;
  1027. }
  1028. rc = hdcp2_app_unload(handle);
  1029. error:
  1030. return rc;
  1031. }
  1032. bool hdcp2_feature_supported_qseecom(void *ctx)
  1033. {
  1034. int rc = 0;
  1035. int retry = 0;
  1036. bool supported = false;
  1037. struct hdcp2_qsee_handle *handle = (struct hdcp2_qsee_handle *)ctx;
  1038. if (!handle) {
  1039. pr_err("invalid input\n");
  1040. rc = -EINVAL;
  1041. goto error;
  1042. }
  1043. if (handle->feature_supported) {
  1044. supported = true;
  1045. goto error;
  1046. }
  1047. rc = hdcp2_app_load(handle);
  1048. if (!rc) {
  1049. do {
  1050. if (!hdcp2_verify_key(handle)) {
  1051. pr_debug("HDCP 2.2 supported.\n");
  1052. pr_debug("hdcp2_verify_key succeeded on %d retry.\n", retry);
  1053. handle->feature_supported = true;
  1054. supported = true;
  1055. break;
  1056. } else if (qseecomd_down) {
  1057. pr_debug("Qseecomd is not up. Going to sleep.\n");
  1058. msleep(SLEEP_QSEECOMD_WAIT_MS);
  1059. retry++;
  1060. } else
  1061. break;
  1062. } while (handle->max_hdcp_key_verify_retries >= retry);
  1063. if (qseecomd_down) {
  1064. pr_err("hdcp2_verify_key failed after %d retries as Qseecomd is not up.\n",
  1065. handle->max_hdcp_key_verify_retries);
  1066. }
  1067. hdcp2_app_unload(handle);
  1068. }
  1069. error:
  1070. return supported;
  1071. }
  1072. int hdcp2_force_encryption_qseecom(void *ctx, uint32_t enable)
  1073. {
  1074. int rc = 0;
  1075. struct hdcp2_qsee_handle *handle = (struct hdcp2_qsee_handle *)ctx;
  1076. hdcp2_app_init_var(force_encryption);
  1077. if (!handle) {
  1078. pr_err("invalid input\n");
  1079. rc = -EINVAL;
  1080. goto error;
  1081. }
  1082. if (handle->hdcp_state == HDCP_STATE_AUTHENTICATED)
  1083. msleep(SLEEP_FORCE_ENCRYPTION_MS);
  1084. req_buf->ctxhandle = handle->tz_ctxhandle;
  1085. req_buf->enable = enable;
  1086. rc = hdcp2_app_process_cmd(force_encryption);
  1087. if (rc || (rsp_buf->commandid != hdcp_cmd_force_encryption))
  1088. goto error;
  1089. error:
  1090. return rc;
  1091. }
  1092. int hdcp2_open_stream_qseecom(void *ctx, uint8_t vc_payload_id,
  1093. uint8_t stream_number, uint32_t *stream_id)
  1094. {
  1095. struct hdcp2_qsee_handle *handle = (struct hdcp2_qsee_handle *)ctx;
  1096. int rc = 0;
  1097. hdcp2_app_init_var(session_open_stream);
  1098. if (!handle) {
  1099. pr_err("invalid input\n");
  1100. rc = -EINVAL;
  1101. goto error;
  1102. }
  1103. if (!(handle->hdcp_state & HDCP_STATE_SESSION_INIT)) {
  1104. pr_err("session not initialized\n");
  1105. rc = -EINVAL;
  1106. goto error;
  1107. }
  1108. if (!(handle->hdcp_state & HDCP_STATE_TXMTR_INIT)) {
  1109. pr_err("txmtr not initialized\n");
  1110. rc = -EINVAL;
  1111. goto error;
  1112. }
  1113. req_buf->sessionid = handle->session_id;
  1114. req_buf->vcpayloadid = vc_payload_id;
  1115. req_buf->stream_number = stream_number;
  1116. req_buf->streamMediaType = 0;
  1117. rc = hdcp2_app_process_cmd(session_open_stream);
  1118. if (rc)
  1119. goto error;
  1120. *stream_id = rsp_buf->streamid;
  1121. pr_debug("success\n");
  1122. error:
  1123. return rc;
  1124. }
  1125. int hdcp2_close_stream_qseecom(void *ctx, uint32_t stream_id)
  1126. {
  1127. struct hdcp2_qsee_handle *handle = (struct hdcp2_qsee_handle *)ctx;
  1128. int rc = 0;
  1129. hdcp2_app_init_var(session_close_stream);
  1130. if (!handle) {
  1131. pr_err("invalid input\n");
  1132. rc = -EINVAL;
  1133. goto error;
  1134. }
  1135. if (!(handle->hdcp_state & HDCP_STATE_SESSION_INIT)) {
  1136. pr_err("session not initialized\n");
  1137. rc = -EINVAL;
  1138. goto error;
  1139. }
  1140. if (!(handle->hdcp_state & HDCP_STATE_TXMTR_INIT)) {
  1141. pr_err("txmtr not initialized\n");
  1142. rc = -EINVAL;
  1143. goto error;
  1144. }
  1145. req_buf->sessionid = handle->session_id;
  1146. req_buf->streamid = stream_id;
  1147. rc = hdcp2_app_process_cmd(session_close_stream);
  1148. if (rc)
  1149. goto error;
  1150. pr_debug("success\n");
  1151. error:
  1152. return rc;
  1153. }
  1154. int hdcp2_update_app_data_qseecom(void *ctx, struct hdcp2_app_data *app_data)
  1155. {
  1156. int rc = 0;
  1157. struct hdcp2_qsee_handle *handle = (struct hdcp2_qsee_handle *)ctx;
  1158. if (!handle) {
  1159. pr_err("invalid input\n");
  1160. rc = -EINVAL;
  1161. goto error;
  1162. }
  1163. app_data->request.data = handle->app_data.request.data;
  1164. app_data->request.length = handle->app_data.request.length;
  1165. app_data->response.data = handle->app_data.response.data;
  1166. app_data->response.length = handle->app_data.response.length;
  1167. app_data->timeout = handle->app_data.timeout;
  1168. app_data->repeater_flag = handle->app_data.repeater_flag;
  1169. error:
  1170. return rc;
  1171. }