All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ramalingam C <ramalingam.c@intel.com>
To: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org,
	daniel.vetter@ffwll.ch, uma.shankar@intel.com
Subject: [PATCH 04/10] drm/i915: Add HDCP SRM Blob parsing
Date: Tue, 26 Feb 2019 13:06:03 +0530	[thread overview]
Message-ID: <1551166569-19683-5-git-send-email-ramalingam.c@intel.com> (raw)
In-Reply-To: <1551166569-19683-1-git-send-email-ramalingam.c@intel.com>

This patch adds a drm blob property to selected connectors.
And also adds capability to parse the new HDCP1.4 srm blob passed
through cp_srm_property.

The revocated KSV list and their counts are stored in
the intel_hdcp. This list should be used for revocation check
of BKSVs in first stage HDCP authentication and for revocation check of
ksv_fifo in second stage authentication.

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c  |   6 +-
 drivers/gpu/drm/i915/intel_drv.h  |   8 ++-
 drivers/gpu/drm/i915/intel_hdcp.c | 147 +++++++++++++++++++++++++++++++++++++-
 include/drm/drm_hdcp.h            |  14 ++++
 4 files changed, 170 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index ffe7759a3f3a..1f935fe9c466 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -3500,7 +3500,8 @@ static void intel_enable_ddi(struct intel_encoder *encoder,
 	if (conn_state->content_protection ==
 	    DRM_MODE_CONTENT_PROTECTION_DESIRED)
 		intel_hdcp_enable(to_intel_connector(conn_state->connector),
-				  (u8)conn_state->cp_content_type);
+				  (u8)conn_state->cp_content_type,
+				  conn_state->cp_srm_blob_id);
 }
 
 static void intel_disable_ddi_dp(struct intel_encoder *encoder,
@@ -3570,7 +3571,8 @@ static void intel_ddi_update_hdcp(struct intel_encoder *encoder,
 	if (conn_state->content_protection ==
 	    DRM_MODE_CONTENT_PROTECTION_DESIRED)
 		intel_hdcp_enable(to_intel_connector(conn_state->connector),
-				  (u8)conn_state->cp_content_type);
+				  (u8)conn_state->cp_content_type,
+				  conn_state->cp_srm_blob_id);
 	else if (conn_state->content_protection ==
 		 DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
 		intel_hdcp_disable(to_intel_connector(conn_state->connector));
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 04cff672aead..53a463d40f43 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -482,6 +482,11 @@ struct intel_hdcp {
 	wait_queue_head_t cp_irq_queue;
 	atomic_t cp_irq_count;
 	int cp_irq_count_cached;
+
+	/* list of Revocated KSVs and their count from SRM blob Parsing */
+	unsigned int revocated_ksv_cnt;
+	u8 *revocated_ksv_list;
+	u32 srm_blob_id;
 };
 
 struct intel_connector {
@@ -2151,7 +2156,8 @@ void intel_hdcp_atomic_check(struct drm_connector *connector,
 			     struct drm_connector_state *new_state);
 int intel_hdcp_init(struct intel_connector *connector,
 		    const struct intel_hdcp_shim *hdcp_shim);
-int intel_hdcp_enable(struct intel_connector *connector, u8 content_type);
+int intel_hdcp_enable(struct intel_connector *connector, u8 content_type,
+		      u32 srm_blob_id);
 int intel_hdcp_disable(struct intel_connector *connector);
 bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port);
 bool intel_hdcp_capable(struct intel_connector *connector);
diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index ab25264a74a4..4b12274d8987 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -1805,6 +1805,10 @@ int intel_hdcp_init(struct intel_connector *connector,
 	if (ret)
 		return ret;
 
+	ret = drm_connector_attach_cp_srm_property(&connector->base);
+	if (ret)
+		return ret;
+
 	hdcp->shim = shim;
 	mutex_init(&hdcp->mutex);
 	INIT_DELAYED_WORK(&hdcp->check_work, intel_hdcp_check_work);
@@ -1817,7 +1821,144 @@ int intel_hdcp_init(struct intel_connector *connector,
 	return 0;
 }
 
-int intel_hdcp_enable(struct intel_connector *connector, u8 content_type)
+static u32 intel_hdcp_get_revocated_ksv_count(u8 *buf, u32 vrls_length)
+{
+	u32 parsed_bytes = 0, ksv_count = 0, vrl_ksv_cnt, vrl_sz;
+
+	do {
+		vrl_ksv_cnt = *buf;
+		ksv_count += vrl_ksv_cnt;
+
+		vrl_sz = (vrl_ksv_cnt * DRM_HDCP_KSV_LEN) + 1;
+		buf += vrl_sz;
+		parsed_bytes += vrl_sz;
+	} while (parsed_bytes < vrls_length);
+
+	return ksv_count;
+}
+
+static u32 intel_hdcp_get_revocated_ksvs(u8 *ksv_list, const u8 *buf,
+					 u32 vrls_length)
+{
+	u32 parsed_bytes = 0, ksv_count = 0;
+	u32 vrl_ksv_cnt, vrl_ksv_sz, vrl_idx = 0;
+
+	do {
+		vrl_ksv_cnt = *buf;
+		vrl_ksv_sz = vrl_ksv_cnt * DRM_HDCP_KSV_LEN;
+		buf++;
+
+		DRM_DEBUG_KMS("vrl: %d, Revoked KSVs: %d\n", vrl_idx++,
+			      vrl_ksv_cnt);
+		memcpy(ksv_list, buf, vrl_ksv_sz);
+		ksv_count += vrl_ksv_cnt;
+		ksv_list += vrl_ksv_sz;
+		buf += vrl_ksv_sz;
+
+		parsed_bytes += (vrl_ksv_sz + 1);
+	} while (parsed_bytes < vrls_length);
+
+	return ksv_count;
+}
+
+static int intel_hdcp_parse_srm(struct drm_connector *connector,
+				struct drm_property_blob *blob)
+{
+	struct intel_hdcp *hdcp = &(to_intel_connector(connector)->hdcp);
+	struct hdcp_srm_header *header;
+	u32 vrl_length, ksv_count;
+	u8 *buf;
+
+	if (blob->length < (sizeof(struct hdcp_srm_header) +
+	    DRM_HDCP_1_4_VRL_LENGTH_SIZE + DRM_HDCP_1_4_DCP_SIG_SIZE)) {
+		DRM_ERROR("Invalid blob length\n");
+		return -EINVAL;
+	}
+
+	header = (struct hdcp_srm_header *)blob->data;
+
+	DRM_DEBUG_KMS("SRM ID: 0x%x, SRM Ver: 0x%x, SRM Gen No: 0x%x\n",
+		      header->spec_indicator.srm_id,
+		      __swab16(header->srm_version), header->srm_gen_no);
+	WARN_ON(header->spec_indicator.reserved_hi ||
+		header->spec_indicator.reserved_lo);
+
+	if (header->spec_indicator.srm_id != DRM_HDCP_1_4_SRM_ID) {
+		DRM_ERROR("Invalid srm_id\n");
+		return -EINVAL;
+	}
+
+	buf = blob->data + sizeof(*header);
+	vrl_length = (*buf << 16 | *(buf + 1) << 8 | *(buf + 2));
+	if (blob->length < (sizeof(struct hdcp_srm_header) + vrl_length) ||
+	    vrl_length < (DRM_HDCP_1_4_VRL_LENGTH_SIZE +
+			  DRM_HDCP_1_4_DCP_SIG_SIZE)) {
+		DRM_ERROR("Invalid blob length or vrl length\n");
+		return -EINVAL;
+	}
+
+	/* Length of the all vrls combined */
+	vrl_length -= (DRM_HDCP_1_4_VRL_LENGTH_SIZE +
+		       DRM_HDCP_1_4_DCP_SIG_SIZE);
+	if (!vrl_length) {
+		DRM_DEBUG("No vrl found\n");
+		return -EINVAL;
+	}
+	buf += DRM_HDCP_1_4_VRL_LENGTH_SIZE;
+
+	ksv_count = intel_hdcp_get_revocated_ksv_count(buf, vrl_length);
+	if (!ksv_count) {
+		DRM_DEBUG_KMS("Revocated KSV count is 0\n");
+		return 0;
+	}
+
+	kfree(hdcp->revocated_ksv_list);
+	hdcp->revocated_ksv_list = kzalloc(ksv_count * DRM_HDCP_KSV_LEN,
+					   GFP_KERNEL);
+	if (!hdcp->revocated_ksv_list) {
+		DRM_ERROR("Out of Memory\n");
+		return -ENOMEM;
+	}
+
+	if (intel_hdcp_get_revocated_ksvs(hdcp->revocated_ksv_list,
+					  buf, vrl_length) != ksv_count) {
+		hdcp->revocated_ksv_cnt = 0;
+		kfree(hdcp->revocated_ksv_list);
+		return -EINVAL;
+	}
+
+	hdcp->revocated_ksv_cnt = ksv_count;
+	return 0;
+}
+
+static void intel_hdcp_update_srm(struct intel_connector *intel_connector,
+				  u32 srm_blob_id)
+{
+	struct drm_connector *connector = &intel_connector->base;
+	struct intel_hdcp *hdcp = &intel_connector->hdcp;
+	struct drm_property_blob *blob;
+
+	DRM_DEBUG_KMS("srm_blob_id %u\n", srm_blob_id);
+
+	if (!srm_blob_id) {
+		kfree(hdcp->revocated_ksv_list);
+		hdcp->revocated_ksv_cnt = 0;
+		hdcp->srm_blob_id = srm_blob_id;
+		return;
+	}
+
+	blob = drm_property_lookup_blob(connector->dev, srm_blob_id);
+	if (!blob || !blob->data)
+		return;
+
+	if (!intel_hdcp_parse_srm(connector, blob))
+		hdcp->srm_blob_id = srm_blob_id;
+
+	drm_property_blob_put(blob);
+}
+
+int intel_hdcp_enable(struct intel_connector *connector, u8 content_type,
+		      u32 srm_blob_id)
 {
 	struct intel_hdcp *hdcp = &connector->hdcp;
 	unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS;
@@ -1828,9 +1969,11 @@ int intel_hdcp_enable(struct intel_connector *connector, u8 content_type)
 
 	mutex_lock(&hdcp->mutex);
 	WARN_ON(hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED);
-
 	hdcp->content_type = content_type;
 
+	if (srm_blob_id != hdcp->srm_blob_id)
+		intel_hdcp_update_srm(connector, srm_blob_id);
+
 	/*
 	 * Considering that HDCP2.2 is more secure than HDCP1.4, If the setup
 	 * is capable of HDCP2.2, it is preferred to use HDCP2.2.
diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
index f243408ecf26..1ccae47fcff5 100644
--- a/include/drm/drm_hdcp.h
+++ b/include/drm/drm_hdcp.h
@@ -265,4 +265,18 @@ void drm_hdcp2_u32_to_seq_num(u8 seq_num[HDCP_2_2_SEQ_NUM_LEN], u32 val)
 	seq_num[2] = val;
 }
 
+#define DRM_HDCP_1_4_SRM_ID			0x8
+#define DRM_HDCP_1_4_VRL_LENGTH_SIZE		3
+#define DRM_HDCP_1_4_DCP_SIG_SIZE		40
+
+struct hdcp_srm_header {
+	struct {
+		u8 reserved_hi:4;
+		u8 srm_id:4;
+		u8 reserved_lo;
+	} spec_indicator;
+	u16 srm_version;
+	u8 srm_gen_no;
+} __packed;
+
 #endif
-- 
2.7.4

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  parent reply	other threads:[~2019-02-26  7:36 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-26  7:35 [PATCH 00/10] HDCP2.2 Phase II Ramalingam C
2019-02-26  7:36 ` [PATCH 01/10] drm: Add CP content type property Ramalingam C
2019-03-05 14:39   ` [Intel-gfx] " Maarten Lankhorst
2019-03-05 19:00     ` C, Ramalingam
2019-02-26  7:36 ` [PATCH 02/10] drm/i915: Attach " Ramalingam C
2019-03-05 14:58   ` [Intel-gfx] " Maarten Lankhorst
2019-02-26  7:36 ` [PATCH 03/10] drm: Add CP System Renewability Msg Property Ramalingam C
2019-02-26  7:36 ` Ramalingam C [this message]
2019-02-26  7:36 ` [PATCH 05/10] drm/i915: Add revocation check on HDCP1.4 Ksvs Ramalingam C
2019-02-26  7:36 ` [PATCH 06/10] drm/i915: SRM parsing and revocation check for HDCP2 Ramalingam C
2019-02-26  7:36 ` [PATCH 07/10] drm: Add CP downstream_info property Ramalingam C
2019-02-26  7:36 ` [PATCH 08/10] drm/i915: Populate downstream info for HDCP1.4 Ramalingam C
2019-02-26  7:36 ` [PATCH 09/10] drm/i915: Populate downstream info for HDCP2.2 Ramalingam C
2019-02-26  7:36 ` [PATCH 10/10] drm/i915: debugfs: HDCP2.2 capability read Ramalingam C
2019-02-26  8:07 ` ✗ Fi.CI.CHECKPATCH: warning for HDCP2.2 Phase II Patchwork
2019-02-26  8:24 ` [PATCH 00/10] " Daniel Vetter
2019-02-26  8:31 ` ✓ Fi.CI.BAT: success for " Patchwork
2019-02-26 11:13 ` ✓ Fi.CI.IGT: " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1551166569-19683-5-git-send-email-ramalingam.c@intel.com \
    --to=ramalingam.c@intel.com \
    --cc=daniel.vetter@ffwll.ch \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=uma.shankar@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.