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