[Intel-gfx] [PATCH v2 4/8] drm/i915: HDCP SRM parsing and revocation check

2019-03-08 Thread Ramalingam C
Implements the SRM table parsing for HDCP 1.4 and 2.2.
And also revocation check is added at authentication of HDCP1.4
and 2.2

Signed-off-by: Ramalingam C 
---
 drivers/gpu/drm/i915/i915_drv.c   |   1 +
 drivers/gpu/drm/i915/i915_drv.h   |   6 +
 drivers/gpu/drm/i915/intel_drv.h  |   2 +
 drivers/gpu/drm/i915/intel_hdcp.c | 308 --
 include/drm/drm_hdcp.h|  32 
 5 files changed, 334 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 0d743907e7bc..6c396ec0f552 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -873,6 +873,7 @@ static int i915_driver_init_early(struct drm_i915_private 
*dev_priv)
mutex_init(&dev_priv->wm.wm_mutex);
mutex_init(&dev_priv->pps_mutex);
mutex_init(&dev_priv->hdcp_comp_mutex);
+   mutex_init(&dev_priv->srm_mutex);
 
i915_memcpy_init_early(dev_priv);
intel_runtime_pm_init_early(dev_priv);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index c4ffe19ec698..c6c7cb1ae1b4 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2054,6 +2054,12 @@ struct drm_i915_private {
/* Mutex to protect the above hdcp component related values. */
struct mutex hdcp_comp_mutex;
 
+   unsigned int revocated_ksv_cnt;
+   u8 *revocated_ksv_list;
+
+   /* Mutex to protect the data about revocated ksvs */
+   struct mutex srm_mutex;
+
/*
 * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
 * will be rejected. Instead look for a better place.
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 186fa035f491..7550f4ed5a98 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -2181,6 +2181,8 @@ void intel_hdcp_component_init(struct drm_i915_private 
*dev_priv);
 void intel_hdcp_component_fini(struct drm_i915_private *dev_priv);
 void intel_hdcp_cleanup(struct intel_connector *connector);
 void intel_hdcp_handle_cp_irq(struct intel_connector *connector);
+ssize_t intel_hdcp_srm_update(struct drm_i915_private *dev_priv, char *buf,
+ size_t count);
 
 /* intel_psr.c */
 #define CAN_PSR(dev_priv) (HAS_PSR(dev_priv) && dev_priv->psr.sink_support)
diff --git a/drivers/gpu/drm/i915/intel_hdcp.c 
b/drivers/gpu/drm/i915/intel_hdcp.c
index ff1bbbee2e52..b1fa81666490 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -273,6 +273,62 @@ 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));
+}
+
+static inline
+struct intel_connector *intel_hdcp_to_connector(struct intel_hdcp *hdcp)
+{
+   return container_of(hdcp, struct intel_connector, hdcp);
+}
+
+/* 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)
+{
+   struct intel_connector *connector = intel_hdcp_to_connector(hdcp);
+   struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
+   struct drm_i915_private *dev_priv =
+   intel_dig_port->base.base.dev->dev_private;
+   u32 rev_ksv_cnt, cnt, i, j;
+   u8 *rev_ksv_list;
+
+   mutex_lock(&dev_priv->srm_mutex);
+   rev_ksv_cnt = dev_priv->revocated_ksv_cnt;
+   rev_ksv_list = dev_priv->revocated_ksv_list;
+
+   /* If the Revocated ksv list is empty */
+   if (!rev_ksv_cnt || !rev_ksv_list) {
+   mutex_unlock(&dev_priv->srm_mutex);
+   return false;
+   }
+
+   for  (cnt = 0; cnt < ksv_count; cnt++) {
+   rev_ksv_list = dev_priv->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);
+   mutex_unlock(&dev_priv->srm_mutex);
+   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;
+   }
+   mutex_unlock(&dev_priv->srm_mutex);
+   return false;
+}
+
 stat

[Intel-gfx] [PATCH v2 4/8] drm/i915: HDCP SRM parsing and revocation check

2019-03-08 Thread Ramalingam C
Implements the SRM table parsing for HDCP 1.4 and 2.2.
And also revocation check is added at authentication of HDCP1.4
and 2.2

Signed-off-by: Ramalingam C 
---
 drivers/gpu/drm/i915/i915_drv.c   |   1 +
 drivers/gpu/drm/i915/i915_drv.h   |   6 +
 drivers/gpu/drm/i915/intel_drv.h  |   2 +
 drivers/gpu/drm/i915/intel_hdcp.c | 308 --
 include/drm/drm_hdcp.h|  32 
 5 files changed, 334 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 0d743907e7bc..6c396ec0f552 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -873,6 +873,7 @@ static int i915_driver_init_early(struct drm_i915_private 
*dev_priv)
mutex_init(&dev_priv->wm.wm_mutex);
mutex_init(&dev_priv->pps_mutex);
mutex_init(&dev_priv->hdcp_comp_mutex);
+   mutex_init(&dev_priv->srm_mutex);
 
i915_memcpy_init_early(dev_priv);
intel_runtime_pm_init_early(dev_priv);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index c4ffe19ec698..c6c7cb1ae1b4 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2054,6 +2054,12 @@ struct drm_i915_private {
/* Mutex to protect the above hdcp component related values. */
struct mutex hdcp_comp_mutex;
 
+   unsigned int revocated_ksv_cnt;
+   u8 *revocated_ksv_list;
+
+   /* Mutex to protect the data about revocated ksvs */
+   struct mutex srm_mutex;
+
/*
 * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
 * will be rejected. Instead look for a better place.
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 186fa035f491..7550f4ed5a98 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -2181,6 +2181,8 @@ void intel_hdcp_component_init(struct drm_i915_private 
*dev_priv);
 void intel_hdcp_component_fini(struct drm_i915_private *dev_priv);
 void intel_hdcp_cleanup(struct intel_connector *connector);
 void intel_hdcp_handle_cp_irq(struct intel_connector *connector);
+ssize_t intel_hdcp_srm_update(struct drm_i915_private *dev_priv, char *buf,
+ size_t count);
 
 /* intel_psr.c */
 #define CAN_PSR(dev_priv) (HAS_PSR(dev_priv) && dev_priv->psr.sink_support)
diff --git a/drivers/gpu/drm/i915/intel_hdcp.c 
b/drivers/gpu/drm/i915/intel_hdcp.c
index ff1bbbee2e52..b1fa81666490 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -273,6 +273,62 @@ 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));
+}
+
+static inline
+struct intel_connector *intel_hdcp_to_connector(struct intel_hdcp *hdcp)
+{
+   return container_of(hdcp, struct intel_connector, hdcp);
+}
+
+/* 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)
+{
+   struct intel_connector *connector = intel_hdcp_to_connector(hdcp);
+   struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
+   struct drm_i915_private *dev_priv =
+   intel_dig_port->base.base.dev->dev_private;
+   u32 rev_ksv_cnt, cnt, i, j;
+   u8 *rev_ksv_list;
+
+   mutex_lock(&dev_priv->srm_mutex);
+   rev_ksv_cnt = dev_priv->revocated_ksv_cnt;
+   rev_ksv_list = dev_priv->revocated_ksv_list;
+
+   /* If the Revocated ksv list is empty */
+   if (!rev_ksv_cnt || !rev_ksv_list) {
+   mutex_unlock(&dev_priv->srm_mutex);
+   return false;
+   }
+
+   for  (cnt = 0; cnt < ksv_count; cnt++) {
+   rev_ksv_list = dev_priv->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);
+   mutex_unlock(&dev_priv->srm_mutex);
+   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;
+   }
+   mutex_unlock(&dev_priv->srm_mutex);
+   return false;
+}
+
 stat