KSV list revocated by DCP LLC is provided as SRM Blob to kernel. Which is parsed and stored in intel_hdcp->revocated_ksv_list. This patch adds the revocation check for BKSV and KSV_FIFO in HDCP1.4 authentication. Signed-off-by: Ramalingam C <ramalingam.c@xxxxxxxxx> --- drivers/gpu/drm/i915/intel_hdcp.c | 67 ++++++++++++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c index 4b12274d8987..7d007de984d7 100644 --- a/drivers/gpu/drm/i915/intel_hdcp.c +++ b/drivers/gpu/drm/i915/intel_hdcp.c @@ -273,6 +273,45 @@ u32 intel_hdcp_get_repeater_ctl(struct intel_digital_port *intel_dig_port) return -EINVAL; } +static inline void intel_hdcp_print_ksv(u8 *ksv) +{ + DRM_DEBUG_KMS("\t%#04x, %#04x, %#04x, %#04x, %#04x\n", *ksv, + *(ksv + 1), *(ksv + 2), *(ksv + 3), *(ksv + 4)); +} + +/* Check if any of the KSV is revocated by DCP LLC through SRM table */ +static inline +bool intel_hdcp_ksvs_revocated(struct intel_hdcp *hdcp, u8 *ksvs, u32 ksv_count) +{ + u32 rev_ksv_cnt = hdcp->revocated_ksv_cnt; + u8 *rev_ksv_list = hdcp->revocated_ksv_list; + u32 cnt, i, j; + + /* If the Revocated ksv list is empty */ + if (!rev_ksv_cnt || !rev_ksv_list) + return false; + + for (cnt = 0; cnt < ksv_count; cnt++) { + rev_ksv_list = hdcp->revocated_ksv_list; + for (i = 0; i < rev_ksv_cnt; i++) { + for (j = 0; j < DRM_HDCP_KSV_LEN; j++) + if (*(ksvs + j) != *(rev_ksv_list + j)) { + break; + } else if (j == (DRM_HDCP_KSV_LEN - 1)) { + DRM_DEBUG_KMS("Revocated KSV is "); + intel_hdcp_print_ksv(ksvs); + return true; + } + /* Move the offset to next KSV in the revocated list */ + rev_ksv_list += DRM_HDCP_KSV_LEN; + } + + /* Iterate to next ksv_offset */ + ksvs += DRM_HDCP_KSV_LEN; + } + return false; +} + static int intel_hdcp_validate_v_prime(struct intel_digital_port *intel_dig_port, const struct intel_hdcp_shim *shim, @@ -490,9 +529,10 @@ int intel_hdcp_validate_v_prime(struct intel_digital_port *intel_dig_port, /* Implements Part 2 of the HDCP authorization procedure */ static -int intel_hdcp_auth_downstream(struct intel_digital_port *intel_dig_port, - const struct intel_hdcp_shim *shim) +int intel_hdcp_auth_downstream(struct intel_hdcp *hdcp, + struct intel_digital_port *intel_dig_port) { + const struct intel_hdcp_shim *shim = hdcp->shim; u8 bstatus[2], num_downstream, *ksv_fifo; int ret, i, tries = 3; @@ -531,6 +571,11 @@ int intel_hdcp_auth_downstream(struct intel_digital_port *intel_dig_port, if (ret) goto err; + if (intel_hdcp_ksvs_revocated(hdcp, ksv_fifo, num_downstream)) { + DRM_ERROR("Revocated Ksv(s) in ksv_fifo\n"); + return -EPERM; + } + /* * When V prime mismatches, DP Spec mandates re-read of * V prime atleast twice. @@ -557,9 +602,11 @@ int intel_hdcp_auth_downstream(struct intel_digital_port *intel_dig_port, } /* Implements Part 1 of the HDCP authorization procedure */ -static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port, - const struct intel_hdcp_shim *shim) +static int intel_hdcp_auth(struct intel_connector *connector) { + struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector); + struct intel_hdcp *hdcp = &connector->hdcp; + const struct intel_hdcp_shim *shim = hdcp->shim; struct drm_i915_private *dev_priv; enum port port; unsigned long r0_prime_gen_start; @@ -625,6 +672,11 @@ static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port, if (ret < 0) return ret; + if (intel_hdcp_ksvs_revocated(hdcp, bksv.shim, 1)) { + DRM_ERROR("BKSV is revocated\n"); + return -EPERM; + } + I915_WRITE(PORT_HDCP_BKSVLO(port), bksv.reg[0]); I915_WRITE(PORT_HDCP_BKSVHI(port), bksv.reg[1]); @@ -698,7 +750,7 @@ static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port, */ if (repeater_present) - return intel_hdcp_auth_downstream(intel_dig_port, shim); + return intel_hdcp_auth_downstream(hdcp, intel_dig_port); DRM_DEBUG_KMS("HDCP is enabled (no repeater present)\n"); return 0; @@ -735,7 +787,6 @@ static int _intel_hdcp_disable(struct intel_connector *connector) static int _intel_hdcp_enable(struct intel_connector *connector) { - struct intel_hdcp *hdcp = &connector->hdcp; struct drm_i915_private *dev_priv = connector->base.dev->dev_private; int i, ret, tries = 3; @@ -760,9 +811,9 @@ static int _intel_hdcp_enable(struct intel_connector *connector) /* Incase of authentication failures, HDCP spec expects reauth. */ for (i = 0; i < tries; i++) { - ret = intel_hdcp_auth(conn_to_dig_port(connector), hdcp->shim); + ret = intel_hdcp_auth(connector); if (!ret) { - hdcp->hdcp_encrypted = true; + connector->hdcp.hdcp_encrypted = true; return 0; } -- 2.7.4 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx