1 | /* |
2 | * Copyright 2018 Advanced Micro Devices, Inc. |
3 | * |
4 | * Permission is hereby granted, free of charge, to any person obtaining a |
5 | * copy of this software and associated documentation files (the "Software"), |
6 | * to deal in the Software without restriction, including without limitation |
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
8 | * and/or sell copies of the Software, and to permit persons to whom the |
9 | * Software is furnished to do so, subject to the following conditions: |
10 | * |
11 | * The above copyright notice and this permission notice shall be included in |
12 | * all copies or substantial portions of the Software. |
13 | * |
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR |
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
20 | * OTHER DEALINGS IN THE SOFTWARE. |
21 | * |
22 | * Authors: AMD |
23 | * |
24 | */ |
25 | |
26 | #define MAX_NUM_DISPLAYS 24 |
27 | |
28 | |
29 | #include "hdcp.h" |
30 | |
31 | #include "amdgpu.h" |
32 | #include "hdcp_psp.h" |
33 | |
34 | static void hdcp2_message_init(struct mod_hdcp *hdcp, |
35 | struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *in) |
36 | { |
37 | in->session_handle = hdcp->auth.id; |
38 | in->prepare.msg1_id = TA_HDCP_HDCP2_MSG_ID__NULL_MESSAGE; |
39 | in->prepare.msg2_id = TA_HDCP_HDCP2_MSG_ID__NULL_MESSAGE; |
40 | in->process.msg1_desc.msg_id = TA_HDCP_HDCP2_MSG_ID__NULL_MESSAGE; |
41 | in->process.msg1_desc.msg_size = 0; |
42 | in->process.msg2_desc.msg_id = TA_HDCP_HDCP2_MSG_ID__NULL_MESSAGE; |
43 | in->process.msg2_desc.msg_size = 0; |
44 | in->process.msg3_desc.msg_id = TA_HDCP_HDCP2_MSG_ID__NULL_MESSAGE; |
45 | in->process.msg3_desc.msg_size = 0; |
46 | } |
47 | |
48 | static enum mod_hdcp_status remove_display_from_topology_v2( |
49 | struct mod_hdcp *hdcp, uint8_t index) |
50 | { |
51 | struct psp_context *psp = hdcp->config.psp.handle; |
52 | struct ta_dtm_shared_memory *dtm_cmd; |
53 | struct mod_hdcp_display *display = |
54 | get_active_display_at_index(hdcp, index); |
55 | enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; |
56 | |
57 | dtm_cmd = (struct ta_dtm_shared_memory *)psp->dtm_context.context.mem_context.shared_buf; |
58 | |
59 | if (!display || !is_display_active(display)) |
60 | return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND; |
61 | |
62 | mutex_lock(&psp->dtm_context.mutex); |
63 | |
64 | memset(dtm_cmd, 0, sizeof(struct ta_dtm_shared_memory)); |
65 | |
66 | dtm_cmd->cmd_id = TA_DTM_COMMAND__TOPOLOGY_UPDATE_V2; |
67 | dtm_cmd->dtm_in_message.topology_update_v2.display_handle = display->index; |
68 | dtm_cmd->dtm_in_message.topology_update_v2.is_active = 0; |
69 | dtm_cmd->dtm_status = TA_DTM_STATUS__GENERIC_FAILURE; |
70 | |
71 | psp_dtm_invoke(psp, ta_cmd_id: dtm_cmd->cmd_id); |
72 | |
73 | if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS) { |
74 | status = MOD_HDCP_STATUS_UPDATE_TOPOLOGY_FAILURE; |
75 | } else { |
76 | display->state = MOD_HDCP_DISPLAY_ACTIVE; |
77 | HDCP_TOP_REMOVE_DISPLAY_TRACE(hdcp, display->index); |
78 | } |
79 | |
80 | mutex_unlock(lock: &psp->dtm_context.mutex); |
81 | return status; |
82 | } |
83 | |
84 | static enum mod_hdcp_status remove_display_from_topology_v3( |
85 | struct mod_hdcp *hdcp, uint8_t index) |
86 | { |
87 | struct psp_context *psp = hdcp->config.psp.handle; |
88 | struct ta_dtm_shared_memory *dtm_cmd; |
89 | struct mod_hdcp_display *display = |
90 | get_active_display_at_index(hdcp, index); |
91 | enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; |
92 | |
93 | dtm_cmd = (struct ta_dtm_shared_memory *)psp->dtm_context.context.mem_context.shared_buf; |
94 | |
95 | if (!display || !is_display_active(display)) |
96 | return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND; |
97 | |
98 | mutex_lock(&psp->dtm_context.mutex); |
99 | |
100 | memset(dtm_cmd, 0, sizeof(struct ta_dtm_shared_memory)); |
101 | |
102 | dtm_cmd->cmd_id = TA_DTM_COMMAND__TOPOLOGY_UPDATE_V3; |
103 | dtm_cmd->dtm_in_message.topology_update_v3.display_handle = display->index; |
104 | dtm_cmd->dtm_in_message.topology_update_v3.is_active = 0; |
105 | dtm_cmd->dtm_status = TA_DTM_STATUS__GENERIC_FAILURE; |
106 | |
107 | psp_dtm_invoke(psp, ta_cmd_id: dtm_cmd->cmd_id); |
108 | mutex_unlock(lock: &psp->dtm_context.mutex); |
109 | |
110 | if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS) { |
111 | status = remove_display_from_topology_v2(hdcp, index); |
112 | if (status != MOD_HDCP_STATUS_SUCCESS) |
113 | display->state = MOD_HDCP_DISPLAY_INACTIVE; |
114 | } else { |
115 | display->state = MOD_HDCP_DISPLAY_ACTIVE; |
116 | HDCP_TOP_REMOVE_DISPLAY_TRACE(hdcp, display->index); |
117 | } |
118 | |
119 | return status; |
120 | } |
121 | |
122 | static enum mod_hdcp_status add_display_to_topology_v2( |
123 | struct mod_hdcp *hdcp, struct mod_hdcp_display *display) |
124 | { |
125 | struct psp_context *psp = hdcp->config.psp.handle; |
126 | struct ta_dtm_shared_memory *dtm_cmd; |
127 | struct mod_hdcp_link *link = &hdcp->connection.link; |
128 | enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; |
129 | |
130 | if (!psp->dtm_context.context.initialized) { |
131 | DRM_INFO("Failed to add display topology, DTM TA is not initialized." ); |
132 | display->state = MOD_HDCP_DISPLAY_INACTIVE; |
133 | return MOD_HDCP_STATUS_FAILURE; |
134 | } |
135 | |
136 | dtm_cmd = (struct ta_dtm_shared_memory *)psp->dtm_context.context.mem_context.shared_buf; |
137 | |
138 | mutex_lock(&psp->dtm_context.mutex); |
139 | memset(dtm_cmd, 0, sizeof(struct ta_dtm_shared_memory)); |
140 | |
141 | dtm_cmd->cmd_id = TA_DTM_COMMAND__TOPOLOGY_UPDATE_V2; |
142 | dtm_cmd->dtm_in_message.topology_update_v2.display_handle = display->index; |
143 | dtm_cmd->dtm_in_message.topology_update_v2.is_active = 1; |
144 | dtm_cmd->dtm_in_message.topology_update_v2.controller = display->controller; |
145 | dtm_cmd->dtm_in_message.topology_update_v2.ddc_line = link->ddc_line; |
146 | dtm_cmd->dtm_in_message.topology_update_v2.dig_be = link->dig_be; |
147 | dtm_cmd->dtm_in_message.topology_update_v2.dig_fe = display->dig_fe; |
148 | if (is_dp_hdcp(hdcp)) |
149 | dtm_cmd->dtm_in_message.topology_update_v2.is_assr = link->dp.assr_enabled; |
150 | |
151 | dtm_cmd->dtm_in_message.topology_update_v2.dp_mst_vcid = display->vc_id; |
152 | dtm_cmd->dtm_in_message.topology_update_v2.max_hdcp_supported_version = |
153 | TA_DTM_HDCP_VERSION_MAX_SUPPORTED__2_2; |
154 | dtm_cmd->dtm_status = TA_DTM_STATUS__GENERIC_FAILURE; |
155 | |
156 | psp_dtm_invoke(psp, ta_cmd_id: dtm_cmd->cmd_id); |
157 | |
158 | if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS) { |
159 | display->state = MOD_HDCP_DISPLAY_INACTIVE; |
160 | status = MOD_HDCP_STATUS_UPDATE_TOPOLOGY_FAILURE; |
161 | } else { |
162 | HDCP_TOP_ADD_DISPLAY_TRACE(hdcp, display->index); |
163 | } |
164 | |
165 | mutex_unlock(lock: &psp->dtm_context.mutex); |
166 | return status; |
167 | } |
168 | |
169 | static enum mod_hdcp_status add_display_to_topology_v3( |
170 | struct mod_hdcp *hdcp, struct mod_hdcp_display *display) |
171 | { |
172 | struct psp_context *psp = hdcp->config.psp.handle; |
173 | struct ta_dtm_shared_memory *dtm_cmd; |
174 | struct mod_hdcp_link *link = &hdcp->connection.link; |
175 | enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; |
176 | |
177 | if (!psp->dtm_context.context.initialized) { |
178 | DRM_INFO("Failed to add display topology, DTM TA is not initialized." ); |
179 | display->state = MOD_HDCP_DISPLAY_INACTIVE; |
180 | return MOD_HDCP_STATUS_FAILURE; |
181 | } |
182 | |
183 | dtm_cmd = (struct ta_dtm_shared_memory *)psp->dtm_context.context.mem_context.shared_buf; |
184 | |
185 | mutex_lock(&psp->dtm_context.mutex); |
186 | memset(dtm_cmd, 0, sizeof(struct ta_dtm_shared_memory)); |
187 | |
188 | dtm_cmd->cmd_id = TA_DTM_COMMAND__TOPOLOGY_UPDATE_V3; |
189 | dtm_cmd->dtm_in_message.topology_update_v3.display_handle = display->index; |
190 | dtm_cmd->dtm_in_message.topology_update_v3.is_active = 1; |
191 | dtm_cmd->dtm_in_message.topology_update_v3.controller = display->controller; |
192 | dtm_cmd->dtm_in_message.topology_update_v3.ddc_line = link->ddc_line; |
193 | dtm_cmd->dtm_in_message.topology_update_v3.link_enc = link->link_enc_idx; |
194 | dtm_cmd->dtm_in_message.topology_update_v3.stream_enc = display->stream_enc_idx; |
195 | if (is_dp_hdcp(hdcp)) |
196 | dtm_cmd->dtm_in_message.topology_update_v3.is_assr = link->dp.assr_enabled; |
197 | |
198 | dtm_cmd->dtm_in_message.topology_update_v3.dp_mst_vcid = display->vc_id; |
199 | dtm_cmd->dtm_in_message.topology_update_v3.max_hdcp_supported_version = |
200 | TA_DTM_HDCP_VERSION_MAX_SUPPORTED__2_3; |
201 | dtm_cmd->dtm_in_message.topology_update_v3.encoder_type = TA_DTM_ENCODER_TYPE__DIG; |
202 | dtm_cmd->dtm_status = TA_DTM_STATUS__GENERIC_FAILURE; |
203 | dtm_cmd->dtm_in_message.topology_update_v3.phy_id = link->phy_idx; |
204 | dtm_cmd->dtm_in_message.topology_update_v3.link_hdcp_cap = link->hdcp_supported_informational; |
205 | dtm_cmd->dtm_in_message.topology_update_v3.dio_output_type = link->dp.usb4_enabled ? |
206 | TA_DTM_DIO_OUTPUT_TYPE__DPIA : |
207 | TA_DTM_DIO_OUTPUT_TYPE__DIRECT; |
208 | dtm_cmd->dtm_in_message.topology_update_v3.dio_output_id = link->dio_output_id; |
209 | |
210 | psp_dtm_invoke(psp, ta_cmd_id: dtm_cmd->cmd_id); |
211 | mutex_unlock(lock: &psp->dtm_context.mutex); |
212 | |
213 | if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS) { |
214 | status = add_display_to_topology_v2(hdcp, display); |
215 | if (status != MOD_HDCP_STATUS_SUCCESS) |
216 | display->state = MOD_HDCP_DISPLAY_INACTIVE; |
217 | } else { |
218 | HDCP_TOP_ADD_DISPLAY_TRACE(hdcp, display->index); |
219 | } |
220 | |
221 | return status; |
222 | } |
223 | |
224 | enum mod_hdcp_status mod_hdcp_remove_display_from_topology( |
225 | struct mod_hdcp *hdcp, uint8_t index) |
226 | { |
227 | enum mod_hdcp_status status = MOD_HDCP_STATUS_UPDATE_TOPOLOGY_FAILURE; |
228 | |
229 | if (hdcp->config.psp.caps.dtm_v3_supported) |
230 | status = remove_display_from_topology_v3(hdcp, index); |
231 | else |
232 | status = remove_display_from_topology_v2(hdcp, index); |
233 | |
234 | return status; |
235 | } |
236 | |
237 | enum mod_hdcp_status mod_hdcp_add_display_to_topology(struct mod_hdcp *hdcp, |
238 | struct mod_hdcp_display *display) |
239 | { |
240 | enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; |
241 | |
242 | if (hdcp->config.psp.caps.dtm_v3_supported) |
243 | status = add_display_to_topology_v3(hdcp, display); |
244 | else |
245 | status = add_display_to_topology_v2(hdcp, display); |
246 | |
247 | return status; |
248 | } |
249 | |
250 | enum mod_hdcp_status mod_hdcp_hdcp1_create_session(struct mod_hdcp *hdcp) |
251 | { |
252 | |
253 | struct psp_context *psp = hdcp->config.psp.handle; |
254 | struct mod_hdcp_display *display = get_first_active_display(hdcp); |
255 | struct ta_hdcp_shared_memory *hdcp_cmd; |
256 | enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; |
257 | |
258 | if (!psp->hdcp_context.context.initialized) { |
259 | DRM_ERROR("Failed to create hdcp session. HDCP TA is not initialized." ); |
260 | return MOD_HDCP_STATUS_FAILURE; |
261 | } |
262 | |
263 | hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf; |
264 | |
265 | mutex_lock(&psp->hdcp_context.mutex); |
266 | memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); |
267 | |
268 | hdcp_cmd->in_msg.hdcp1_create_session.display_handle = display->index; |
269 | hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP1_CREATE_SESSION; |
270 | |
271 | psp_hdcp_invoke(psp, ta_cmd_id: hdcp_cmd->cmd_id); |
272 | |
273 | hdcp->auth.id = hdcp_cmd->out_msg.hdcp1_create_session.session_handle; |
274 | |
275 | if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) { |
276 | status = MOD_HDCP_STATUS_HDCP1_CREATE_SESSION_FAILURE; |
277 | } else { |
278 | hdcp->auth.msg.hdcp1.ainfo = hdcp_cmd->out_msg.hdcp1_create_session.ainfo_primary; |
279 | memcpy(hdcp->auth.msg.hdcp1.aksv, hdcp_cmd->out_msg.hdcp1_create_session.aksv_primary, |
280 | sizeof(hdcp->auth.msg.hdcp1.aksv)); |
281 | memcpy(hdcp->auth.msg.hdcp1.an, hdcp_cmd->out_msg.hdcp1_create_session.an_primary, |
282 | sizeof(hdcp->auth.msg.hdcp1.an)); |
283 | } |
284 | |
285 | mutex_unlock(lock: &psp->hdcp_context.mutex); |
286 | return status; |
287 | } |
288 | |
289 | enum mod_hdcp_status mod_hdcp_hdcp1_destroy_session(struct mod_hdcp *hdcp) |
290 | { |
291 | |
292 | struct psp_context *psp = hdcp->config.psp.handle; |
293 | struct ta_hdcp_shared_memory *hdcp_cmd; |
294 | uint8_t i = 0; |
295 | enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; |
296 | |
297 | mutex_lock(&psp->hdcp_context.mutex); |
298 | hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf; |
299 | memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); |
300 | |
301 | hdcp_cmd->in_msg.hdcp1_destroy_session.session_handle = hdcp->auth.id; |
302 | hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP1_DESTROY_SESSION; |
303 | |
304 | psp_hdcp_invoke(psp, ta_cmd_id: hdcp_cmd->cmd_id); |
305 | |
306 | if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) { |
307 | status = MOD_HDCP_STATUS_HDCP1_DESTROY_SESSION_FAILURE; |
308 | } else { |
309 | HDCP_TOP_HDCP1_DESTROY_SESSION_TRACE(hdcp); |
310 | for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++) |
311 | if (is_display_encryption_enabled(display: &hdcp->displays[i])) { |
312 | hdcp->displays[i].state = |
313 | MOD_HDCP_DISPLAY_ACTIVE; |
314 | HDCP_HDCP1_DISABLED_TRACE( |
315 | hdcp, hdcp->displays[i].index); |
316 | } |
317 | } |
318 | |
319 | mutex_unlock(lock: &psp->hdcp_context.mutex); |
320 | return status; |
321 | } |
322 | |
323 | enum mod_hdcp_status mod_hdcp_hdcp1_validate_rx(struct mod_hdcp *hdcp) |
324 | { |
325 | struct psp_context *psp = hdcp->config.psp.handle; |
326 | struct ta_hdcp_shared_memory *hdcp_cmd; |
327 | enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; |
328 | |
329 | mutex_lock(&psp->hdcp_context.mutex); |
330 | hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf; |
331 | memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); |
332 | |
333 | hdcp_cmd->in_msg.hdcp1_first_part_authentication.session_handle = hdcp->auth.id; |
334 | |
335 | memcpy(hdcp_cmd->in_msg.hdcp1_first_part_authentication.bksv_primary, hdcp->auth.msg.hdcp1.bksv, |
336 | TA_HDCP__HDCP1_KSV_SIZE); |
337 | |
338 | hdcp_cmd->in_msg.hdcp1_first_part_authentication.r0_prime_primary = hdcp->auth.msg.hdcp1.r0p; |
339 | hdcp_cmd->in_msg.hdcp1_first_part_authentication.bcaps = hdcp->auth.msg.hdcp1.bcaps; |
340 | hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP1_FIRST_PART_AUTHENTICATION; |
341 | |
342 | psp_hdcp_invoke(psp, ta_cmd_id: hdcp_cmd->cmd_id); |
343 | |
344 | if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) { |
345 | status = MOD_HDCP_STATUS_HDCP1_VALIDATE_RX_FAILURE; |
346 | } else if (hdcp_cmd->out_msg.hdcp1_first_part_authentication.authentication_status == |
347 | TA_HDCP_AUTHENTICATION_STATUS__HDCP1_FIRST_PART_COMPLETE) { |
348 | /* needs second part of authentication */ |
349 | hdcp->connection.is_repeater = 1; |
350 | } else if (hdcp_cmd->out_msg.hdcp1_first_part_authentication.authentication_status == |
351 | TA_HDCP_AUTHENTICATION_STATUS__HDCP1_AUTHENTICATED) { |
352 | hdcp->connection.is_repeater = 0; |
353 | } else if (hdcp_cmd->out_msg.hdcp1_first_part_authentication.authentication_status == |
354 | TA_HDCP_AUTHENTICATION_STATUS__HDCP1_KSV_REVOKED) { |
355 | hdcp->connection.is_hdcp1_revoked = 1; |
356 | status = MOD_HDCP_STATUS_HDCP1_BKSV_REVOKED; |
357 | } else |
358 | status = MOD_HDCP_STATUS_HDCP1_VALIDATE_RX_FAILURE; |
359 | |
360 | mutex_unlock(lock: &psp->hdcp_context.mutex); |
361 | return status; |
362 | } |
363 | |
364 | enum mod_hdcp_status mod_hdcp_hdcp1_enable_encryption(struct mod_hdcp *hdcp) |
365 | { |
366 | struct psp_context *psp = hdcp->config.psp.handle; |
367 | struct ta_hdcp_shared_memory *hdcp_cmd; |
368 | struct mod_hdcp_display *display = get_first_active_display(hdcp); |
369 | enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; |
370 | |
371 | mutex_lock(&psp->hdcp_context.mutex); |
372 | hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf; |
373 | memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); |
374 | |
375 | hdcp_cmd->in_msg.hdcp1_enable_encryption.session_handle = hdcp->auth.id; |
376 | hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP1_ENABLE_ENCRYPTION; |
377 | |
378 | psp_hdcp_invoke(psp, ta_cmd_id: hdcp_cmd->cmd_id); |
379 | |
380 | if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) { |
381 | status = MOD_HDCP_STATUS_HDCP1_ENABLE_ENCRYPTION_FAILURE; |
382 | } else if (!is_dp_mst_hdcp(hdcp)) { |
383 | display->state = MOD_HDCP_DISPLAY_ENCRYPTION_ENABLED; |
384 | HDCP_HDCP1_ENABLED_TRACE(hdcp, display->index); |
385 | } |
386 | |
387 | mutex_unlock(lock: &psp->hdcp_context.mutex); |
388 | return status; |
389 | } |
390 | |
391 | enum mod_hdcp_status mod_hdcp_hdcp1_validate_ksvlist_vp(struct mod_hdcp *hdcp) |
392 | { |
393 | struct psp_context *psp = hdcp->config.psp.handle; |
394 | struct ta_hdcp_shared_memory *hdcp_cmd; |
395 | enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; |
396 | |
397 | mutex_lock(&psp->hdcp_context.mutex); |
398 | hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf; |
399 | memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); |
400 | |
401 | hdcp_cmd->in_msg.hdcp1_second_part_authentication.session_handle = hdcp->auth.id; |
402 | |
403 | hdcp_cmd->in_msg.hdcp1_second_part_authentication.ksv_list_size = hdcp->auth.msg.hdcp1.ksvlist_size; |
404 | memcpy(hdcp_cmd->in_msg.hdcp1_second_part_authentication.ksv_list, hdcp->auth.msg.hdcp1.ksvlist, |
405 | hdcp->auth.msg.hdcp1.ksvlist_size); |
406 | |
407 | memcpy(hdcp_cmd->in_msg.hdcp1_second_part_authentication.v_prime, hdcp->auth.msg.hdcp1.vp, |
408 | sizeof(hdcp->auth.msg.hdcp1.vp)); |
409 | |
410 | hdcp_cmd->in_msg.hdcp1_second_part_authentication.bstatus_binfo = |
411 | is_dp_hdcp(hdcp) ? hdcp->auth.msg.hdcp1.binfo_dp : hdcp->auth.msg.hdcp1.bstatus; |
412 | hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP1_SECOND_PART_AUTHENTICATION; |
413 | |
414 | psp_hdcp_invoke(psp, ta_cmd_id: hdcp_cmd->cmd_id); |
415 | |
416 | if (hdcp_cmd->hdcp_status == TA_HDCP_STATUS__SUCCESS && |
417 | hdcp_cmd->out_msg.hdcp1_second_part_authentication.authentication_status == |
418 | TA_HDCP_AUTHENTICATION_STATUS__HDCP1_AUTHENTICATED) { |
419 | status = MOD_HDCP_STATUS_SUCCESS; |
420 | } else if (hdcp_cmd->out_msg.hdcp1_second_part_authentication.authentication_status == |
421 | TA_HDCP_AUTHENTICATION_STATUS__HDCP1_KSV_REVOKED) { |
422 | hdcp->connection.is_hdcp1_revoked = 1; |
423 | status = MOD_HDCP_STATUS_HDCP1_KSV_LIST_REVOKED; |
424 | } else { |
425 | status = MOD_HDCP_STATUS_HDCP1_VALIDATE_KSV_LIST_FAILURE; |
426 | } |
427 | |
428 | mutex_unlock(lock: &psp->hdcp_context.mutex); |
429 | return status; |
430 | } |
431 | |
432 | enum mod_hdcp_status mod_hdcp_hdcp1_enable_dp_stream_encryption(struct mod_hdcp *hdcp) |
433 | { |
434 | |
435 | struct psp_context *psp = hdcp->config.psp.handle; |
436 | struct ta_hdcp_shared_memory *hdcp_cmd; |
437 | int i = 0; |
438 | enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; |
439 | |
440 | mutex_lock(&psp->hdcp_context.mutex); |
441 | hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf; |
442 | |
443 | for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++) { |
444 | |
445 | if (hdcp->displays[i].adjust.disable || hdcp->displays[i].state != MOD_HDCP_DISPLAY_ACTIVE) |
446 | continue; |
447 | |
448 | memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); |
449 | |
450 | hdcp_cmd->in_msg.hdcp1_enable_dp_stream_encryption.session_handle = hdcp->auth.id; |
451 | hdcp_cmd->in_msg.hdcp1_enable_dp_stream_encryption.display_handle = hdcp->displays[i].index; |
452 | hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP1_ENABLE_DP_STREAM_ENCRYPTION; |
453 | |
454 | psp_hdcp_invoke(psp, ta_cmd_id: hdcp_cmd->cmd_id); |
455 | |
456 | if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) { |
457 | status = MOD_HDCP_STATUS_HDCP1_ENABLE_STREAM_ENCRYPTION_FAILURE; |
458 | break; |
459 | } |
460 | |
461 | hdcp->displays[i].state = MOD_HDCP_DISPLAY_ENCRYPTION_ENABLED; |
462 | HDCP_HDCP1_ENABLED_TRACE(hdcp, hdcp->displays[i].index); |
463 | } |
464 | |
465 | mutex_unlock(lock: &psp->hdcp_context.mutex); |
466 | return status; |
467 | } |
468 | |
469 | enum mod_hdcp_status mod_hdcp_hdcp1_link_maintenance(struct mod_hdcp *hdcp) |
470 | { |
471 | struct psp_context *psp = hdcp->config.psp.handle; |
472 | struct ta_hdcp_shared_memory *hdcp_cmd; |
473 | enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; |
474 | |
475 | mutex_lock(&psp->hdcp_context.mutex); |
476 | hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf; |
477 | |
478 | memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); |
479 | |
480 | hdcp_cmd->in_msg.hdcp1_get_encryption_status.session_handle = hdcp->auth.id; |
481 | |
482 | hdcp_cmd->out_msg.hdcp1_get_encryption_status.protection_level = 0; |
483 | hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP1_GET_ENCRYPTION_STATUS; |
484 | |
485 | psp_hdcp_invoke(psp, ta_cmd_id: hdcp_cmd->cmd_id); |
486 | |
487 | if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS || |
488 | hdcp_cmd->out_msg.hdcp1_get_encryption_status.protection_level != 1) |
489 | status = MOD_HDCP_STATUS_HDCP1_LINK_MAINTENANCE_FAILURE; |
490 | |
491 | mutex_unlock(lock: &psp->hdcp_context.mutex); |
492 | return status; |
493 | } |
494 | |
495 | enum mod_hdcp_status mod_hdcp_hdcp2_create_session(struct mod_hdcp *hdcp) |
496 | { |
497 | struct psp_context *psp = hdcp->config.psp.handle; |
498 | struct ta_hdcp_shared_memory *hdcp_cmd; |
499 | struct mod_hdcp_display *display = get_first_active_display(hdcp); |
500 | enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; |
501 | |
502 | |
503 | if (!psp->hdcp_context.context.initialized) { |
504 | DRM_ERROR("Failed to create hdcp session, HDCP TA is not initialized" ); |
505 | return MOD_HDCP_STATUS_FAILURE; |
506 | } |
507 | |
508 | if (!display) |
509 | return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND; |
510 | |
511 | mutex_lock(&psp->hdcp_context.mutex); |
512 | |
513 | hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf; |
514 | memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); |
515 | |
516 | if (!display) |
517 | return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND; |
518 | |
519 | hdcp_cmd->in_msg.hdcp2_create_session_v2.display_handle = display->index; |
520 | |
521 | if (hdcp->connection.link.adjust.hdcp2.force_type == MOD_HDCP_FORCE_TYPE_0) |
522 | hdcp_cmd->in_msg.hdcp2_create_session_v2.negotiate_content_type = |
523 | TA_HDCP2_CONTENT_TYPE_NEGOTIATION_TYPE__FORCE_TYPE0; |
524 | else if (hdcp->connection.link.adjust.hdcp2.force_type == MOD_HDCP_FORCE_TYPE_1) |
525 | hdcp_cmd->in_msg.hdcp2_create_session_v2.negotiate_content_type = |
526 | TA_HDCP2_CONTENT_TYPE_NEGOTIATION_TYPE__FORCE_TYPE1; |
527 | else if (hdcp->connection.link.adjust.hdcp2.force_type == MOD_HDCP_FORCE_TYPE_MAX) |
528 | hdcp_cmd->in_msg.hdcp2_create_session_v2.negotiate_content_type = |
529 | TA_HDCP2_CONTENT_TYPE_NEGOTIATION_TYPE__MAX_SUPPORTED; |
530 | |
531 | hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_CREATE_SESSION_V2; |
532 | |
533 | psp_hdcp_invoke(psp, ta_cmd_id: hdcp_cmd->cmd_id); |
534 | |
535 | |
536 | if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) |
537 | status = MOD_HDCP_STATUS_HDCP2_CREATE_SESSION_FAILURE; |
538 | else |
539 | hdcp->auth.id = hdcp_cmd->out_msg.hdcp2_create_session_v2.session_handle; |
540 | |
541 | mutex_unlock(lock: &psp->hdcp_context.mutex); |
542 | return status; |
543 | } |
544 | |
545 | enum mod_hdcp_status mod_hdcp_hdcp2_destroy_session(struct mod_hdcp *hdcp) |
546 | { |
547 | struct psp_context *psp = hdcp->config.psp.handle; |
548 | struct ta_hdcp_shared_memory *hdcp_cmd; |
549 | uint8_t i = 0; |
550 | enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; |
551 | |
552 | mutex_lock(&psp->hdcp_context.mutex); |
553 | hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf; |
554 | memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); |
555 | |
556 | hdcp_cmd->in_msg.hdcp2_destroy_session.session_handle = hdcp->auth.id; |
557 | hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_DESTROY_SESSION; |
558 | |
559 | psp_hdcp_invoke(psp, ta_cmd_id: hdcp_cmd->cmd_id); |
560 | |
561 | if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) { |
562 | status = MOD_HDCP_STATUS_HDCP2_DESTROY_SESSION_FAILURE; |
563 | } else { |
564 | HDCP_TOP_HDCP2_DESTROY_SESSION_TRACE(hdcp); |
565 | for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++) |
566 | if (is_display_encryption_enabled(display: &hdcp->displays[i])) { |
567 | hdcp->displays[i].state = |
568 | MOD_HDCP_DISPLAY_ACTIVE; |
569 | HDCP_HDCP2_DISABLED_TRACE( |
570 | hdcp, hdcp->displays[i].index); |
571 | } |
572 | } |
573 | |
574 | mutex_unlock(lock: &psp->hdcp_context.mutex); |
575 | return status; |
576 | } |
577 | |
578 | enum mod_hdcp_status mod_hdcp_hdcp2_prepare_ake_init(struct mod_hdcp *hdcp) |
579 | { |
580 | struct psp_context *psp = hdcp->config.psp.handle; |
581 | struct ta_hdcp_shared_memory *hdcp_cmd; |
582 | struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in; |
583 | struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out; |
584 | enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; |
585 | |
586 | mutex_lock(&psp->hdcp_context.mutex); |
587 | hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf; |
588 | memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); |
589 | |
590 | msg_in = &hdcp_cmd->in_msg.hdcp2_prepare_process_authentication_message_v2; |
591 | msg_out = &hdcp_cmd->out_msg.hdcp2_prepare_process_authentication_message_v2; |
592 | |
593 | hdcp2_message_init(hdcp, in: msg_in); |
594 | |
595 | hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2; |
596 | msg_in->prepare.msg1_id = TA_HDCP_HDCP2_MSG_ID__AKE_INIT; |
597 | |
598 | psp_hdcp_invoke(psp, ta_cmd_id: hdcp_cmd->cmd_id); |
599 | |
600 | if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) |
601 | status = MOD_HDCP_STATUS_HDCP2_PREP_AKE_INIT_FAILURE; |
602 | else |
603 | memcpy(&hdcp->auth.msg.hdcp2.ake_init[0], &msg_out->prepare.transmitter_message[0], |
604 | sizeof(hdcp->auth.msg.hdcp2.ake_init)); |
605 | |
606 | mutex_unlock(lock: &psp->hdcp_context.mutex); |
607 | return status; |
608 | } |
609 | |
610 | enum mod_hdcp_status mod_hdcp_hdcp2_validate_ake_cert(struct mod_hdcp *hdcp) |
611 | { |
612 | struct psp_context *psp = hdcp->config.psp.handle; |
613 | struct ta_hdcp_shared_memory *hdcp_cmd; |
614 | struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in; |
615 | struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out; |
616 | enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; |
617 | |
618 | mutex_lock(&psp->hdcp_context.mutex); |
619 | hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf; |
620 | memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); |
621 | |
622 | msg_in = &hdcp_cmd->in_msg.hdcp2_prepare_process_authentication_message_v2; |
623 | msg_out = &hdcp_cmd->out_msg.hdcp2_prepare_process_authentication_message_v2; |
624 | |
625 | hdcp2_message_init(hdcp, in: msg_in); |
626 | |
627 | msg_in->process.msg1_desc.msg_id = TA_HDCP_HDCP2_MSG_ID__AKE_SEND_CERT; |
628 | msg_in->process.msg1_desc.msg_size = TA_HDCP_HDCP2_MSG_ID_MAX_SIZE__AKE_SEND_CERT; |
629 | |
630 | memcpy(&msg_in->process.receiver_message[0], hdcp->auth.msg.hdcp2.ake_cert, |
631 | sizeof(hdcp->auth.msg.hdcp2.ake_cert)); |
632 | |
633 | msg_in->prepare.msg1_id = TA_HDCP_HDCP2_MSG_ID__AKE_NO_STORED_KM; |
634 | msg_in->prepare.msg2_id = TA_HDCP_HDCP2_MSG_ID__AKE_STORED_KM; |
635 | |
636 | hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2; |
637 | |
638 | psp_hdcp_invoke(psp, ta_cmd_id: hdcp_cmd->cmd_id); |
639 | |
640 | if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) { |
641 | status = MOD_HDCP_STATUS_HDCP2_VALIDATE_AKE_CERT_FAILURE; |
642 | } else { |
643 | memcpy(hdcp->auth.msg.hdcp2.ake_no_stored_km, |
644 | &msg_out->prepare.transmitter_message[0], |
645 | sizeof(hdcp->auth.msg.hdcp2.ake_no_stored_km)); |
646 | |
647 | memcpy(hdcp->auth.msg.hdcp2.ake_stored_km, |
648 | &msg_out->prepare.transmitter_message[sizeof(hdcp->auth.msg.hdcp2.ake_no_stored_km)], |
649 | sizeof(hdcp->auth.msg.hdcp2.ake_stored_km)); |
650 | |
651 | if (msg_out->process.msg1_status == |
652 | TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS) { |
653 | hdcp->connection.is_km_stored = |
654 | msg_out->process.is_km_stored ? 1 : 0; |
655 | hdcp->connection.is_repeater = |
656 | msg_out->process.is_repeater ? 1 : 0; |
657 | status = MOD_HDCP_STATUS_SUCCESS; |
658 | } else if (msg_out->process.msg1_status == |
659 | TA_HDCP2_MSG_AUTHENTICATION_STATUS__RECEIVERID_REVOKED) { |
660 | hdcp->connection.is_hdcp2_revoked = 1; |
661 | status = MOD_HDCP_STATUS_HDCP2_AKE_CERT_REVOKED; |
662 | } else { |
663 | status = MOD_HDCP_STATUS_HDCP2_VALIDATE_AKE_CERT_FAILURE; |
664 | } |
665 | } |
666 | mutex_unlock(lock: &psp->hdcp_context.mutex); |
667 | return status; |
668 | } |
669 | |
670 | enum mod_hdcp_status mod_hdcp_hdcp2_validate_h_prime(struct mod_hdcp *hdcp) |
671 | { |
672 | struct psp_context *psp = hdcp->config.psp.handle; |
673 | struct ta_hdcp_shared_memory *hdcp_cmd; |
674 | struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in; |
675 | struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out; |
676 | enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; |
677 | |
678 | mutex_lock(&psp->hdcp_context.mutex); |
679 | hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf; |
680 | memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); |
681 | |
682 | msg_in = &hdcp_cmd->in_msg.hdcp2_prepare_process_authentication_message_v2; |
683 | msg_out = &hdcp_cmd->out_msg.hdcp2_prepare_process_authentication_message_v2; |
684 | |
685 | hdcp2_message_init(hdcp, in: msg_in); |
686 | |
687 | msg_in->process.msg1_desc.msg_id = TA_HDCP_HDCP2_MSG_ID__AKE_SEND_H_PRIME; |
688 | msg_in->process.msg1_desc.msg_size = TA_HDCP_HDCP2_MSG_ID_MAX_SIZE__AKE_SEND_H_PRIME; |
689 | |
690 | memcpy(&msg_in->process.receiver_message[0], hdcp->auth.msg.hdcp2.ake_h_prime, |
691 | sizeof(hdcp->auth.msg.hdcp2.ake_h_prime)); |
692 | |
693 | if (!hdcp->connection.is_km_stored) { |
694 | msg_in->process.msg2_desc.msg_id = TA_HDCP_HDCP2_MSG_ID__AKE_SEND_PAIRING_INFO; |
695 | msg_in->process.msg2_desc.msg_size = TA_HDCP_HDCP2_MSG_ID_MAX_SIZE__AKE_SEND_PAIRING_INFO; |
696 | memcpy(&msg_in->process.receiver_message[sizeof(hdcp->auth.msg.hdcp2.ake_h_prime)], |
697 | hdcp->auth.msg.hdcp2.ake_pairing_info, sizeof(hdcp->auth.msg.hdcp2.ake_pairing_info)); |
698 | } |
699 | |
700 | hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2; |
701 | |
702 | psp_hdcp_invoke(psp, ta_cmd_id: hdcp_cmd->cmd_id); |
703 | |
704 | if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) |
705 | status = MOD_HDCP_STATUS_HDCP2_VALIDATE_H_PRIME_FAILURE; |
706 | else if (msg_out->process.msg1_status != TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS) |
707 | status = MOD_HDCP_STATUS_HDCP2_VALIDATE_H_PRIME_FAILURE; |
708 | else if (!hdcp->connection.is_km_stored && |
709 | msg_out->process.msg2_status != TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS) |
710 | status = MOD_HDCP_STATUS_HDCP2_VALIDATE_PAIRING_INFO_FAILURE; |
711 | |
712 | mutex_unlock(lock: &psp->hdcp_context.mutex); |
713 | return status; |
714 | } |
715 | |
716 | enum mod_hdcp_status mod_hdcp_hdcp2_prepare_lc_init(struct mod_hdcp *hdcp) |
717 | { |
718 | struct psp_context *psp = hdcp->config.psp.handle; |
719 | struct ta_hdcp_shared_memory *hdcp_cmd; |
720 | struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in; |
721 | struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out; |
722 | enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; |
723 | |
724 | mutex_lock(&psp->hdcp_context.mutex); |
725 | hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf; |
726 | memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); |
727 | |
728 | msg_in = &hdcp_cmd->in_msg.hdcp2_prepare_process_authentication_message_v2; |
729 | msg_out = &hdcp_cmd->out_msg.hdcp2_prepare_process_authentication_message_v2; |
730 | |
731 | hdcp2_message_init(hdcp, in: msg_in); |
732 | |
733 | msg_in->prepare.msg1_id = TA_HDCP_HDCP2_MSG_ID__LC_INIT; |
734 | |
735 | hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2; |
736 | |
737 | psp_hdcp_invoke(psp, ta_cmd_id: hdcp_cmd->cmd_id); |
738 | |
739 | if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) |
740 | status = MOD_HDCP_STATUS_HDCP2_PREP_LC_INIT_FAILURE; |
741 | else |
742 | memcpy(hdcp->auth.msg.hdcp2.lc_init, &msg_out->prepare.transmitter_message[0], |
743 | sizeof(hdcp->auth.msg.hdcp2.lc_init)); |
744 | |
745 | mutex_unlock(lock: &psp->hdcp_context.mutex); |
746 | return status; |
747 | } |
748 | |
749 | enum mod_hdcp_status mod_hdcp_hdcp2_validate_l_prime(struct mod_hdcp *hdcp) |
750 | { |
751 | struct psp_context *psp = hdcp->config.psp.handle; |
752 | struct ta_hdcp_shared_memory *hdcp_cmd; |
753 | struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in; |
754 | struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out; |
755 | enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; |
756 | |
757 | mutex_lock(&psp->hdcp_context.mutex); |
758 | hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf; |
759 | memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); |
760 | |
761 | msg_in = &hdcp_cmd->in_msg.hdcp2_prepare_process_authentication_message_v2; |
762 | msg_out = &hdcp_cmd->out_msg.hdcp2_prepare_process_authentication_message_v2; |
763 | |
764 | hdcp2_message_init(hdcp, in: msg_in); |
765 | |
766 | msg_in->process.msg1_desc.msg_id = TA_HDCP_HDCP2_MSG_ID__LC_SEND_L_PRIME; |
767 | msg_in->process.msg1_desc.msg_size = TA_HDCP_HDCP2_MSG_ID_MAX_SIZE__LC_SEND_L_PRIME; |
768 | |
769 | memcpy(&msg_in->process.receiver_message[0], hdcp->auth.msg.hdcp2.lc_l_prime, |
770 | sizeof(hdcp->auth.msg.hdcp2.lc_l_prime)); |
771 | |
772 | hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2; |
773 | |
774 | psp_hdcp_invoke(psp, ta_cmd_id: hdcp_cmd->cmd_id); |
775 | |
776 | if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS || |
777 | msg_out->process.msg1_status != TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS) |
778 | status = MOD_HDCP_STATUS_HDCP2_VALIDATE_L_PRIME_FAILURE; |
779 | |
780 | mutex_unlock(lock: &psp->hdcp_context.mutex); |
781 | return status; |
782 | } |
783 | |
784 | enum mod_hdcp_status mod_hdcp_hdcp2_prepare_eks(struct mod_hdcp *hdcp) |
785 | { |
786 | struct psp_context *psp = hdcp->config.psp.handle; |
787 | struct ta_hdcp_shared_memory *hdcp_cmd; |
788 | struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in; |
789 | struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out; |
790 | enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; |
791 | |
792 | mutex_lock(&psp->hdcp_context.mutex); |
793 | hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf; |
794 | memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); |
795 | |
796 | msg_in = &hdcp_cmd->in_msg.hdcp2_prepare_process_authentication_message_v2; |
797 | msg_out = &hdcp_cmd->out_msg.hdcp2_prepare_process_authentication_message_v2; |
798 | |
799 | hdcp2_message_init(hdcp, in: msg_in); |
800 | |
801 | msg_in->prepare.msg1_id = TA_HDCP_HDCP2_MSG_ID__SKE_SEND_EKS; |
802 | |
803 | if (is_dp_hdcp(hdcp)) |
804 | msg_in->prepare.msg2_id = TA_HDCP_HDCP2_MSG_ID__SIGNAL_CONTENT_STREAM_TYPE_DP; |
805 | |
806 | hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2; |
807 | psp_hdcp_invoke(psp, ta_cmd_id: hdcp_cmd->cmd_id); |
808 | |
809 | if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) { |
810 | status = MOD_HDCP_STATUS_HDCP2_PREP_EKS_FAILURE; |
811 | } else { |
812 | memcpy(hdcp->auth.msg.hdcp2.ske_eks, |
813 | &msg_out->prepare.transmitter_message[0], |
814 | sizeof(hdcp->auth.msg.hdcp2.ske_eks)); |
815 | msg_out->prepare.msg1_desc.msg_size = |
816 | sizeof(hdcp->auth.msg.hdcp2.ske_eks); |
817 | |
818 | if (is_dp_hdcp(hdcp)) { |
819 | memcpy(hdcp->auth.msg.hdcp2.content_stream_type_dp, |
820 | &msg_out->prepare.transmitter_message[sizeof(hdcp->auth.msg.hdcp2.ske_eks)], |
821 | sizeof(hdcp->auth.msg.hdcp2.content_stream_type_dp)); |
822 | } |
823 | } |
824 | mutex_unlock(lock: &psp->hdcp_context.mutex); |
825 | |
826 | return status; |
827 | } |
828 | |
829 | enum mod_hdcp_status mod_hdcp_hdcp2_enable_encryption(struct mod_hdcp *hdcp) |
830 | { |
831 | struct psp_context *psp = hdcp->config.psp.handle; |
832 | struct ta_hdcp_shared_memory *hdcp_cmd; |
833 | struct mod_hdcp_display *display = get_first_active_display(hdcp); |
834 | enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; |
835 | |
836 | if (!display) |
837 | return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND; |
838 | |
839 | mutex_lock(&psp->hdcp_context.mutex); |
840 | |
841 | hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf; |
842 | memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); |
843 | |
844 | hdcp_cmd->in_msg.hdcp2_set_encryption.session_handle = hdcp->auth.id; |
845 | |
846 | hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_SET_ENCRYPTION; |
847 | psp_hdcp_invoke(psp, ta_cmd_id: hdcp_cmd->cmd_id); |
848 | |
849 | if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) { |
850 | status = MOD_HDCP_STATUS_HDCP2_ENABLE_ENCRYPTION_FAILURE; |
851 | } else if (!is_dp_mst_hdcp(hdcp)) { |
852 | display->state = MOD_HDCP_DISPLAY_ENCRYPTION_ENABLED; |
853 | HDCP_HDCP2_ENABLED_TRACE(hdcp, display->index); |
854 | } |
855 | |
856 | mutex_unlock(lock: &psp->hdcp_context.mutex); |
857 | return status; |
858 | } |
859 | |
860 | enum mod_hdcp_status mod_hdcp_hdcp2_validate_rx_id_list(struct mod_hdcp *hdcp) |
861 | { |
862 | struct psp_context *psp = hdcp->config.psp.handle; |
863 | struct ta_hdcp_shared_memory *hdcp_cmd; |
864 | struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in; |
865 | struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out; |
866 | enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; |
867 | |
868 | mutex_lock(&psp->hdcp_context.mutex); |
869 | |
870 | hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf; |
871 | memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); |
872 | |
873 | msg_in = &hdcp_cmd->in_msg.hdcp2_prepare_process_authentication_message_v2; |
874 | msg_out = &hdcp_cmd->out_msg.hdcp2_prepare_process_authentication_message_v2; |
875 | |
876 | hdcp2_message_init(hdcp, in: msg_in); |
877 | |
878 | msg_in->process.msg1_desc.msg_id = TA_HDCP_HDCP2_MSG_ID__REPEATERAUTH_SEND_RECEIVERID_LIST; |
879 | msg_in->process.msg1_desc.msg_size = sizeof(hdcp->auth.msg.hdcp2.rx_id_list); |
880 | memcpy(&msg_in->process.receiver_message[0], hdcp->auth.msg.hdcp2.rx_id_list, |
881 | sizeof(hdcp->auth.msg.hdcp2.rx_id_list)); |
882 | |
883 | msg_in->prepare.msg1_id = TA_HDCP_HDCP2_MSG_ID__REPEATERAUTH_SEND_ACK; |
884 | |
885 | hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2; |
886 | |
887 | psp_hdcp_invoke(psp, ta_cmd_id: hdcp_cmd->cmd_id); |
888 | |
889 | if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) { |
890 | status = MOD_HDCP_STATUS_HDCP2_VALIDATE_RX_ID_LIST_FAILURE; |
891 | } else { |
892 | memcpy(hdcp->auth.msg.hdcp2.repeater_auth_ack, |
893 | &msg_out->prepare.transmitter_message[0], |
894 | sizeof(hdcp->auth.msg.hdcp2.repeater_auth_ack)); |
895 | |
896 | if (msg_out->process.msg1_status == |
897 | TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS) { |
898 | hdcp->connection.is_km_stored = msg_out->process.is_km_stored ? 1 : 0; |
899 | hdcp->connection.is_repeater = msg_out->process.is_repeater ? 1 : 0; |
900 | status = MOD_HDCP_STATUS_SUCCESS; |
901 | } else if (msg_out->process.msg1_status == |
902 | TA_HDCP2_MSG_AUTHENTICATION_STATUS__RECEIVERID_REVOKED) { |
903 | hdcp->connection.is_hdcp2_revoked = 1; |
904 | status = MOD_HDCP_STATUS_HDCP2_RX_ID_LIST_REVOKED; |
905 | } else { |
906 | status = MOD_HDCP_STATUS_HDCP2_VALIDATE_RX_ID_LIST_FAILURE; |
907 | } |
908 | } |
909 | mutex_unlock(lock: &psp->hdcp_context.mutex); |
910 | return status; |
911 | } |
912 | |
913 | enum mod_hdcp_status mod_hdcp_hdcp2_enable_dp_stream_encryption(struct mod_hdcp *hdcp) |
914 | { |
915 | struct psp_context *psp = hdcp->config.psp.handle; |
916 | struct ta_hdcp_shared_memory *hdcp_cmd; |
917 | struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in; |
918 | uint8_t i; |
919 | enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; |
920 | |
921 | mutex_lock(&psp->hdcp_context.mutex); |
922 | hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf; |
923 | memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); |
924 | |
925 | msg_in = &hdcp_cmd->in_msg.hdcp2_prepare_process_authentication_message_v2; |
926 | |
927 | hdcp2_message_init(hdcp, in: msg_in); |
928 | |
929 | |
930 | for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++) { |
931 | if (hdcp->displays[i].adjust.disable || hdcp->displays[i].state != MOD_HDCP_DISPLAY_ACTIVE) |
932 | continue; |
933 | |
934 | hdcp_cmd->in_msg.hdcp2_enable_dp_stream_encryption.display_handle = hdcp->displays[i].index; |
935 | hdcp_cmd->in_msg.hdcp2_enable_dp_stream_encryption.session_handle = hdcp->auth.id; |
936 | |
937 | hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_ENABLE_DP_STREAM_ENCRYPTION; |
938 | psp_hdcp_invoke(psp, ta_cmd_id: hdcp_cmd->cmd_id); |
939 | |
940 | if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) |
941 | break; |
942 | |
943 | hdcp->displays[i].state = MOD_HDCP_DISPLAY_ENCRYPTION_ENABLED; |
944 | HDCP_HDCP2_ENABLED_TRACE(hdcp, hdcp->displays[i].index); |
945 | } |
946 | |
947 | if (hdcp_cmd->hdcp_status == TA_HDCP_STATUS__SUCCESS) |
948 | status = MOD_HDCP_STATUS_SUCCESS; |
949 | else |
950 | status = MOD_HDCP_STATUS_HDCP2_ENABLE_STREAM_ENCRYPTION_FAILURE; |
951 | |
952 | mutex_unlock(lock: &psp->hdcp_context.mutex); |
953 | return status; |
954 | } |
955 | |
956 | enum mod_hdcp_status mod_hdcp_hdcp2_prepare_stream_management(struct mod_hdcp *hdcp) |
957 | { |
958 | |
959 | struct psp_context *psp = hdcp->config.psp.handle; |
960 | struct ta_hdcp_shared_memory *hdcp_cmd; |
961 | struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in; |
962 | struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out; |
963 | enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; |
964 | |
965 | mutex_lock(&psp->hdcp_context.mutex); |
966 | hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf; |
967 | memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); |
968 | |
969 | msg_in = &hdcp_cmd->in_msg.hdcp2_prepare_process_authentication_message_v2; |
970 | msg_out = &hdcp_cmd->out_msg.hdcp2_prepare_process_authentication_message_v2; |
971 | |
972 | hdcp2_message_init(hdcp, in: msg_in); |
973 | |
974 | msg_in->prepare.msg1_id = TA_HDCP_HDCP2_MSG_ID__REPEATERAUTH_STREAM_MANAGE; |
975 | |
976 | |
977 | hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2; |
978 | psp_hdcp_invoke(psp, ta_cmd_id: hdcp_cmd->cmd_id); |
979 | |
980 | if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) { |
981 | status = MOD_HDCP_STATUS_HDCP2_PREPARE_STREAM_MANAGEMENT_FAILURE; |
982 | } else { |
983 | hdcp->auth.msg.hdcp2.stream_manage_size = msg_out->prepare.msg1_desc.msg_size; |
984 | |
985 | memcpy(hdcp->auth.msg.hdcp2.repeater_auth_stream_manage, |
986 | &msg_out->prepare.transmitter_message[0], |
987 | sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_manage)); |
988 | } |
989 | mutex_unlock(lock: &psp->hdcp_context.mutex); |
990 | return status; |
991 | } |
992 | |
993 | enum mod_hdcp_status mod_hdcp_hdcp2_validate_stream_ready(struct mod_hdcp *hdcp) |
994 | { |
995 | struct psp_context *psp = hdcp->config.psp.handle; |
996 | struct ta_hdcp_shared_memory *hdcp_cmd; |
997 | struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in; |
998 | struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out; |
999 | enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; |
1000 | |
1001 | mutex_lock(&psp->hdcp_context.mutex); |
1002 | hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf; |
1003 | memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); |
1004 | |
1005 | msg_in = &hdcp_cmd->in_msg.hdcp2_prepare_process_authentication_message_v2; |
1006 | msg_out = &hdcp_cmd->out_msg.hdcp2_prepare_process_authentication_message_v2; |
1007 | |
1008 | hdcp2_message_init(hdcp, in: msg_in); |
1009 | |
1010 | msg_in->process.msg1_desc.msg_id = TA_HDCP_HDCP2_MSG_ID__REPEATERAUTH_STREAM_READY; |
1011 | |
1012 | msg_in->process.msg1_desc.msg_size = sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_ready); |
1013 | |
1014 | memcpy(&msg_in->process.receiver_message[0], hdcp->auth.msg.hdcp2.repeater_auth_stream_ready, |
1015 | sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_ready)); |
1016 | |
1017 | hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2; |
1018 | psp_hdcp_invoke(psp, ta_cmd_id: hdcp_cmd->cmd_id); |
1019 | |
1020 | if (hdcp_cmd->hdcp_status == TA_HDCP_STATUS__SUCCESS && |
1021 | msg_out->process.msg1_status == TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS) |
1022 | status = MOD_HDCP_STATUS_SUCCESS; |
1023 | else |
1024 | status = MOD_HDCP_STATUS_HDCP2_VALIDATE_STREAM_READY_FAILURE; |
1025 | |
1026 | mutex_unlock(lock: &psp->hdcp_context.mutex); |
1027 | return status; |
1028 | } |
1029 | |