1 /* 2 * Copyright 2019 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 #include "hdcp.h" 27 28 static inline enum mod_hdcp_status validate_bksv(struct mod_hdcp *hdcp) 29 { 30 uint64_t n = 0; 31 uint8_t count = 0; 32 u8 bksv[sizeof(n)] = { }; 33 34 memcpy(bksv, hdcp->auth.msg.hdcp1.bksv, sizeof(hdcp->auth.msg.hdcp1.bksv)); 35 n = *(uint64_t *)bksv; 36 37 while (n) { 38 count++; 39 n &= (n - 1); 40 } 41 return (count == 20) ? MOD_HDCP_STATUS_SUCCESS : 42 MOD_HDCP_STATUS_HDCP1_INVALID_BKSV; 43 } 44 45 static inline enum mod_hdcp_status check_ksv_ready(struct mod_hdcp *hdcp) 46 { 47 if (is_dp_hdcp(hdcp)) 48 return (hdcp->auth.msg.hdcp1.bstatus & DP_BSTATUS_READY) ? 49 MOD_HDCP_STATUS_SUCCESS : 50 MOD_HDCP_STATUS_HDCP1_KSV_LIST_NOT_READY; 51 return (hdcp->auth.msg.hdcp1.bcaps & DRM_HDCP_DDC_BCAPS_KSV_FIFO_READY) ? 52 MOD_HDCP_STATUS_SUCCESS : 53 MOD_HDCP_STATUS_HDCP1_KSV_LIST_NOT_READY; 54 } 55 56 static inline enum mod_hdcp_status check_hdcp_capable_dp(struct mod_hdcp *hdcp) 57 { 58 return (hdcp->auth.msg.hdcp1.bcaps & DP_BCAPS_HDCP_CAPABLE) ? 59 MOD_HDCP_STATUS_SUCCESS : 60 MOD_HDCP_STATUS_HDCP1_NOT_CAPABLE; 61 } 62 63 static inline enum mod_hdcp_status check_r0p_available_dp(struct mod_hdcp *hdcp) 64 { 65 enum mod_hdcp_status status; 66 if (is_dp_hdcp(hdcp)) { 67 status = (hdcp->auth.msg.hdcp1.bstatus & 68 DP_BSTATUS_R0_PRIME_READY) ? 69 MOD_HDCP_STATUS_SUCCESS : 70 MOD_HDCP_STATUS_HDCP1_R0_PRIME_PENDING; 71 } else { 72 status = MOD_HDCP_STATUS_INVALID_OPERATION; 73 } 74 return status; 75 } 76 77 static inline enum mod_hdcp_status check_link_integrity_dp( 78 struct mod_hdcp *hdcp) 79 { 80 return (hdcp->auth.msg.hdcp1.bstatus & 81 DP_BSTATUS_LINK_FAILURE) ? 82 MOD_HDCP_STATUS_HDCP1_LINK_INTEGRITY_FAILURE : 83 MOD_HDCP_STATUS_SUCCESS; 84 } 85 86 static inline enum mod_hdcp_status check_no_reauthentication_request_dp( 87 struct mod_hdcp *hdcp) 88 { 89 return (hdcp->auth.msg.hdcp1.bstatus & DP_BSTATUS_REAUTH_REQ) ? 90 MOD_HDCP_STATUS_HDCP1_REAUTH_REQUEST_ISSUED : 91 MOD_HDCP_STATUS_SUCCESS; 92 } 93 94 static inline enum mod_hdcp_status check_no_max_cascade(struct mod_hdcp *hdcp) 95 { 96 enum mod_hdcp_status status; 97 98 if (is_dp_hdcp(hdcp)) 99 status = DRM_HDCP_MAX_CASCADE_EXCEEDED(hdcp->auth.msg.hdcp1.binfo_dp >> 8) 100 ? MOD_HDCP_STATUS_HDCP1_MAX_CASCADE_EXCEEDED_FAILURE 101 : MOD_HDCP_STATUS_SUCCESS; 102 else 103 status = DRM_HDCP_MAX_CASCADE_EXCEEDED(hdcp->auth.msg.hdcp1.bstatus >> 8) 104 ? MOD_HDCP_STATUS_HDCP1_MAX_CASCADE_EXCEEDED_FAILURE 105 : MOD_HDCP_STATUS_SUCCESS; 106 return status; 107 } 108 109 static inline enum mod_hdcp_status check_no_max_devs(struct mod_hdcp *hdcp) 110 { 111 enum mod_hdcp_status status; 112 113 if (is_dp_hdcp(hdcp)) 114 status = DRM_HDCP_MAX_DEVICE_EXCEEDED(hdcp->auth.msg.hdcp1.binfo_dp) ? 115 MOD_HDCP_STATUS_HDCP1_MAX_DEVS_EXCEEDED_FAILURE : 116 MOD_HDCP_STATUS_SUCCESS; 117 else 118 status = DRM_HDCP_MAX_DEVICE_EXCEEDED(hdcp->auth.msg.hdcp1.bstatus) ? 119 MOD_HDCP_STATUS_HDCP1_MAX_DEVS_EXCEEDED_FAILURE : 120 MOD_HDCP_STATUS_SUCCESS; 121 return status; 122 } 123 124 static inline uint8_t get_device_count(struct mod_hdcp *hdcp) 125 { 126 return is_dp_hdcp(hdcp) ? 127 DRM_HDCP_NUM_DOWNSTREAM(hdcp->auth.msg.hdcp1.binfo_dp) : 128 DRM_HDCP_NUM_DOWNSTREAM(hdcp->auth.msg.hdcp1.bstatus); 129 } 130 131 static inline enum mod_hdcp_status check_device_count(struct mod_hdcp *hdcp) 132 { 133 /* device count must be greater than or equal to tracked hdcp displays */ 134 return (get_device_count(hdcp) < get_active_display_count(hdcp)) ? 135 MOD_HDCP_STATUS_HDCP1_DEVICE_COUNT_MISMATCH_FAILURE : 136 MOD_HDCP_STATUS_SUCCESS; 137 } 138 139 static enum mod_hdcp_status wait_for_active_rx(struct mod_hdcp *hdcp, 140 struct mod_hdcp_event_context *event_ctx, 141 struct mod_hdcp_transition_input_hdcp1 *input) 142 { 143 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 144 145 if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) { 146 event_ctx->unexpected_event = 1; 147 goto out; 148 } 149 150 if (!mod_hdcp_execute_and_set(mod_hdcp_read_bksv, 151 &input->bksv_read, &status, 152 hdcp, "bksv_read")) 153 goto out; 154 if (!mod_hdcp_execute_and_set(mod_hdcp_read_bcaps, 155 &input->bcaps_read, &status, 156 hdcp, "bcaps_read")) 157 goto out; 158 out: 159 return status; 160 } 161 162 static enum mod_hdcp_status exchange_ksvs(struct mod_hdcp *hdcp, 163 struct mod_hdcp_event_context *event_ctx, 164 struct mod_hdcp_transition_input_hdcp1 *input) 165 { 166 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 167 168 if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) { 169 event_ctx->unexpected_event = 1; 170 goto out; 171 } 172 173 if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp1_create_session, 174 &input->create_session, &status, 175 hdcp, "create_session")) 176 goto out; 177 if (!mod_hdcp_execute_and_set(mod_hdcp_write_an, 178 &input->an_write, &status, 179 hdcp, "an_write")) 180 goto out; 181 if (!mod_hdcp_execute_and_set(mod_hdcp_write_aksv, 182 &input->aksv_write, &status, 183 hdcp, "aksv_write")) 184 goto out; 185 if (!mod_hdcp_execute_and_set(mod_hdcp_read_bksv, 186 &input->bksv_read, &status, 187 hdcp, "bksv_read")) 188 goto out; 189 if (!mod_hdcp_execute_and_set(validate_bksv, 190 &input->bksv_validation, &status, 191 hdcp, "bksv_validation")) 192 goto out; 193 if (hdcp->auth.msg.hdcp1.ainfo) { 194 if (!mod_hdcp_execute_and_set(mod_hdcp_write_ainfo, 195 &input->ainfo_write, &status, 196 hdcp, "ainfo_write")) 197 goto out; 198 } 199 out: 200 return status; 201 } 202 203 static enum mod_hdcp_status computations_validate_rx_test_for_repeater( 204 struct mod_hdcp *hdcp, 205 struct mod_hdcp_event_context *event_ctx, 206 struct mod_hdcp_transition_input_hdcp1 *input) 207 { 208 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 209 210 if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) { 211 event_ctx->unexpected_event = 1; 212 goto out; 213 } 214 215 if (!mod_hdcp_execute_and_set(mod_hdcp_read_r0p, 216 &input->r0p_read, &status, 217 hdcp, "r0p_read")) 218 goto out; 219 if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp1_validate_rx, 220 &input->rx_validation, &status, 221 hdcp, "rx_validation")) 222 goto out; 223 if (hdcp->connection.is_repeater) { 224 if (!hdcp->connection.link.adjust.hdcp1.postpone_encryption) 225 if (!mod_hdcp_execute_and_set( 226 mod_hdcp_hdcp1_enable_encryption, 227 &input->encryption, &status, 228 hdcp, "encryption")) 229 goto out; 230 } else { 231 if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp1_enable_encryption, 232 &input->encryption, &status, 233 hdcp, "encryption")) 234 goto out; 235 if (is_dp_mst_hdcp(hdcp)) 236 if (!mod_hdcp_execute_and_set( 237 mod_hdcp_hdcp1_enable_dp_stream_encryption, 238 &input->stream_encryption_dp, &status, 239 hdcp, "stream_encryption_dp")) 240 goto out; 241 } 242 out: 243 return status; 244 } 245 246 static enum mod_hdcp_status authenticated(struct mod_hdcp *hdcp, 247 struct mod_hdcp_event_context *event_ctx, 248 struct mod_hdcp_transition_input_hdcp1 *input) 249 { 250 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 251 252 if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) { 253 event_ctx->unexpected_event = 1; 254 goto out; 255 } 256 257 if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp1_link_maintenance, 258 &input->link_maintenance, &status, 259 hdcp, "link_maintenance")) 260 goto out; 261 out: 262 return status; 263 } 264 265 static enum mod_hdcp_status wait_for_ready(struct mod_hdcp *hdcp, 266 struct mod_hdcp_event_context *event_ctx, 267 struct mod_hdcp_transition_input_hdcp1 *input) 268 { 269 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 270 271 if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK && 272 event_ctx->event != MOD_HDCP_EVENT_CPIRQ && 273 event_ctx->event != MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) { 274 event_ctx->unexpected_event = 1; 275 goto out; 276 } 277 278 if (is_dp_hdcp(hdcp)) { 279 if (!mod_hdcp_execute_and_set(mod_hdcp_read_bstatus, 280 &input->bstatus_read, &status, 281 hdcp, "bstatus_read")) 282 goto out; 283 if (!mod_hdcp_execute_and_set(check_link_integrity_dp, 284 &input->link_integrity_check, &status, 285 hdcp, "link_integrity_check")) 286 goto out; 287 if (!mod_hdcp_execute_and_set(check_no_reauthentication_request_dp, 288 &input->reauth_request_check, &status, 289 hdcp, "reauth_request_check")) 290 goto out; 291 } else { 292 if (!mod_hdcp_execute_and_set(mod_hdcp_read_bcaps, 293 &input->bcaps_read, &status, 294 hdcp, "bcaps_read")) 295 goto out; 296 } 297 if (!mod_hdcp_execute_and_set(check_ksv_ready, 298 &input->ready_check, &status, 299 hdcp, "ready_check")) 300 goto out; 301 out: 302 return status; 303 } 304 305 static enum mod_hdcp_status read_ksv_list(struct mod_hdcp *hdcp, 306 struct mod_hdcp_event_context *event_ctx, 307 struct mod_hdcp_transition_input_hdcp1 *input) 308 { 309 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 310 uint8_t device_count; 311 312 if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) { 313 event_ctx->unexpected_event = 1; 314 goto out; 315 } 316 317 if (is_dp_hdcp(hdcp)) { 318 if (!mod_hdcp_execute_and_set(mod_hdcp_read_binfo, 319 &input->binfo_read_dp, &status, 320 hdcp, "binfo_read_dp")) 321 goto out; 322 } else { 323 if (!mod_hdcp_execute_and_set(mod_hdcp_read_bstatus, 324 &input->bstatus_read, &status, 325 hdcp, "bstatus_read")) 326 goto out; 327 } 328 if (!mod_hdcp_execute_and_set(check_no_max_cascade, 329 &input->max_cascade_check, &status, 330 hdcp, "max_cascade_check")) 331 goto out; 332 if (!mod_hdcp_execute_and_set(check_no_max_devs, 333 &input->max_devs_check, &status, 334 hdcp, "max_devs_check")) 335 goto out; 336 if (!mod_hdcp_execute_and_set(check_device_count, 337 &input->device_count_check, &status, 338 hdcp, "device_count_check")) 339 goto out; 340 device_count = get_device_count(hdcp); 341 hdcp->auth.msg.hdcp1.ksvlist_size = device_count*5; 342 if (!mod_hdcp_execute_and_set(mod_hdcp_read_ksvlist, 343 &input->ksvlist_read, &status, 344 hdcp, "ksvlist_read")) 345 goto out; 346 if (!mod_hdcp_execute_and_set(mod_hdcp_read_vp, 347 &input->vp_read, &status, 348 hdcp, "vp_read")) 349 goto out; 350 if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp1_validate_ksvlist_vp, 351 &input->ksvlist_vp_validation, &status, 352 hdcp, "ksvlist_vp_validation")) 353 goto out; 354 if (input->encryption != PASS) 355 if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp1_enable_encryption, 356 &input->encryption, &status, 357 hdcp, "encryption")) 358 goto out; 359 if (is_dp_mst_hdcp(hdcp)) 360 if (!mod_hdcp_execute_and_set( 361 mod_hdcp_hdcp1_enable_dp_stream_encryption, 362 &input->stream_encryption_dp, &status, 363 hdcp, "stream_encryption_dp")) 364 goto out; 365 out: 366 return status; 367 } 368 369 static enum mod_hdcp_status determine_rx_hdcp_capable_dp(struct mod_hdcp *hdcp, 370 struct mod_hdcp_event_context *event_ctx, 371 struct mod_hdcp_transition_input_hdcp1 *input) 372 { 373 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 374 375 if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) { 376 event_ctx->unexpected_event = 1; 377 goto out; 378 } 379 380 if (!mod_hdcp_execute_and_set(mod_hdcp_read_bcaps, 381 &input->bcaps_read, &status, 382 hdcp, "bcaps_read")) 383 goto out; 384 if (!mod_hdcp_execute_and_set(check_hdcp_capable_dp, 385 &input->hdcp_capable_dp, &status, 386 hdcp, "hdcp_capable_dp")) 387 goto out; 388 out: 389 return status; 390 } 391 392 static enum mod_hdcp_status wait_for_r0_prime_dp(struct mod_hdcp *hdcp, 393 struct mod_hdcp_event_context *event_ctx, 394 struct mod_hdcp_transition_input_hdcp1 *input) 395 { 396 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 397 398 if (event_ctx->event != MOD_HDCP_EVENT_CPIRQ && 399 event_ctx->event != MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) { 400 event_ctx->unexpected_event = 1; 401 goto out; 402 } 403 404 if (!mod_hdcp_execute_and_set(mod_hdcp_read_bstatus, 405 &input->bstatus_read, &status, 406 hdcp, "bstatus_read")) 407 goto out; 408 if (!mod_hdcp_execute_and_set(check_r0p_available_dp, 409 &input->r0p_available_dp, &status, 410 hdcp, "r0p_available_dp")) 411 goto out; 412 out: 413 return status; 414 } 415 416 static enum mod_hdcp_status authenticated_dp(struct mod_hdcp *hdcp, 417 struct mod_hdcp_event_context *event_ctx, 418 struct mod_hdcp_transition_input_hdcp1 *input) 419 { 420 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 421 422 if (event_ctx->event != MOD_HDCP_EVENT_CPIRQ) { 423 event_ctx->unexpected_event = 1; 424 goto out; 425 } 426 427 if (!mod_hdcp_execute_and_set(mod_hdcp_read_bstatus, 428 &input->bstatus_read, &status, 429 hdcp, "bstatus_read")) 430 goto out; 431 if (!mod_hdcp_execute_and_set(check_link_integrity_dp, 432 &input->link_integrity_check, &status, 433 hdcp, "link_integrity_check")) 434 goto out; 435 if (!mod_hdcp_execute_and_set(check_no_reauthentication_request_dp, 436 &input->reauth_request_check, &status, 437 hdcp, "reauth_request_check")) 438 goto out; 439 out: 440 return status; 441 } 442 443 uint8_t mod_hdcp_execute_and_set( 444 mod_hdcp_action func, uint8_t *flag, 445 enum mod_hdcp_status *status, struct mod_hdcp *hdcp, char *str) 446 { 447 *status = func(hdcp); 448 if (*status == MOD_HDCP_STATUS_SUCCESS && *flag != PASS) { 449 HDCP_INPUT_PASS_TRACE(hdcp, str); 450 *flag = PASS; 451 } else if (*status != MOD_HDCP_STATUS_SUCCESS && *flag != FAIL) { 452 HDCP_INPUT_FAIL_TRACE(hdcp, str); 453 *flag = FAIL; 454 } 455 return (*status == MOD_HDCP_STATUS_SUCCESS); 456 } 457 458 enum mod_hdcp_status mod_hdcp_hdcp1_execution(struct mod_hdcp *hdcp, 459 struct mod_hdcp_event_context *event_ctx, 460 struct mod_hdcp_transition_input_hdcp1 *input) 461 { 462 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 463 464 switch (current_state(hdcp)) { 465 case H1_A0_WAIT_FOR_ACTIVE_RX: 466 status = wait_for_active_rx(hdcp, event_ctx, input); 467 break; 468 case H1_A1_EXCHANGE_KSVS: 469 status = exchange_ksvs(hdcp, event_ctx, input); 470 break; 471 case H1_A2_COMPUTATIONS_A3_VALIDATE_RX_A6_TEST_FOR_REPEATER: 472 status = computations_validate_rx_test_for_repeater(hdcp, 473 event_ctx, input); 474 break; 475 case H1_A45_AUTHENTICATED: 476 status = authenticated(hdcp, event_ctx, input); 477 break; 478 case H1_A8_WAIT_FOR_READY: 479 status = wait_for_ready(hdcp, event_ctx, input); 480 break; 481 case H1_A9_READ_KSV_LIST: 482 status = read_ksv_list(hdcp, event_ctx, input); 483 break; 484 default: 485 status = MOD_HDCP_STATUS_INVALID_STATE; 486 break; 487 } 488 489 return status; 490 } 491 492 extern enum mod_hdcp_status mod_hdcp_hdcp1_dp_execution(struct mod_hdcp *hdcp, 493 struct mod_hdcp_event_context *event_ctx, 494 struct mod_hdcp_transition_input_hdcp1 *input) 495 { 496 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 497 498 switch (current_state(hdcp)) { 499 case D1_A0_DETERMINE_RX_HDCP_CAPABLE: 500 status = determine_rx_hdcp_capable_dp(hdcp, event_ctx, input); 501 break; 502 case D1_A1_EXCHANGE_KSVS: 503 status = exchange_ksvs(hdcp, event_ctx, input); 504 break; 505 case D1_A23_WAIT_FOR_R0_PRIME: 506 status = wait_for_r0_prime_dp(hdcp, event_ctx, input); 507 break; 508 case D1_A2_COMPUTATIONS_A3_VALIDATE_RX_A5_TEST_FOR_REPEATER: 509 status = computations_validate_rx_test_for_repeater( 510 hdcp, event_ctx, input); 511 break; 512 case D1_A4_AUTHENTICATED: 513 status = authenticated_dp(hdcp, event_ctx, input); 514 break; 515 case D1_A6_WAIT_FOR_READY: 516 status = wait_for_ready(hdcp, event_ctx, input); 517 break; 518 case D1_A7_READ_KSV_LIST: 519 status = read_ksv_list(hdcp, event_ctx, input); 520 break; 521 default: 522 status = MOD_HDCP_STATUS_INVALID_STATE; 523 break; 524 } 525 526 return status; 527 } 528