From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: "Romli, Khairul Anuar" Date: Thu, 21 Dec 2017 13:55:41 +0530 Subject: [PATCH] drm/i915: Add revocation check on Ksvs KSV list revocated by DCP LLC is provided as SRM Blob to kernel. Which is parsed and stored in intel_connector->revocated_ksv_list. This patch adds the revocation check for BKSV and KSV_FIFO in case of repeater. Signed-off-by: Ramalingam C --- drivers/gpu/drm/i915/intel_hdcp.c | 49 +++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c index ca2c73469cb2..20f78b572d1b 100644 --- a/drivers/gpu/drm/i915/intel_hdcp.c +++ b/drivers/gpu/drm/i915/intel_hdcp.c @@ -185,6 +185,45 @@ struct intel_digital_port *conn_to_dig_port(struct intel_connector *connector) return enc_to_dig_port(&intel_attached_encoder(&connector->base)->base); } +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_connector *connector, + u8 *ksvs, u32 ksv_count) +{ + u32 rev_ksv_cnt = connector->revocated_ksv_cnt; + u8 *rev_ksv_list = connector->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 = connector->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; +} + /* Implements Part 2 of the HDCP authorization procedure */ static int intel_hdcp_auth_downstream(struct intel_connector *connector) @@ -235,6 +274,11 @@ int intel_hdcp_auth_downstream(struct intel_connector *connector) if (ret) return ret; + if (intel_hdcp_ksvs_revocated(connector, ksv_fifo, num_downstream)) { + DRM_ERROR("Revocated Ksv(s) in ksv_fifo\n"); + return -EPERM; + } + /* Process V' values from the receiver */ for (i = 0; i < DRM_HDCP_V_PRIME_NUM_PARTS; i++) { ret = shim->read_v_prime_part(intel_dig_port, i, &vprime); @@ -519,6 +563,11 @@ static int intel_hdcp_auth(struct intel_connector *connector) return -ENODEV; } + if (intel_hdcp_ksvs_revocated(connector, 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]); -- https://clearlinux.org