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