diff mbox

[v3,16/40] misc/mei/hdcp: Verify M_prime

Message ID 1522763873-23041-17-git-send-email-ramalingam.c@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Ramalingam C April 3, 2018, 1:57 p.m. UTC
Request to ME to verify the M_Prime received from the HDCP sink.

ME FW will calculate the M and compare with M_prime received
as part of RepeaterAuth_Stream_Ready, which is HDCP2.2 protocol msg.

On successful completion of this stage, downstream propagation of
the stream management info is completed.

v2:
  Rebased.
v3:
  cldev is passed as first parameter [Tomas]
  Redundant comments and cast are removed [Tomas]

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
---
 drivers/misc/mei/hdcp/mei_hdcp.c | 79 ++++++++++++++++++++++++++++++++++++++++
 include/linux/mei_hdcp.h         |  8 ++++
 2 files changed, 87 insertions(+)

Comments

Uma Shankar May 9, 2018, 1:50 p.m. UTC | #1
>-----Original Message-----

>From: dri-devel [mailto:dri-devel-bounces@lists.freedesktop.org] On Behalf Of

>Ramalingam C

>Sent: Tuesday, April 3, 2018 7:27 PM

>To: intel-gfx@lists.freedesktop.org; dri-devel@lists.freedesktop.org;

>seanpaul@chromium.org; daniel@ffwll.ch; chris@chris-wilson.co.uk;

>jani.nikula@linux.intel.com; Winkler, Tomas <tomas.winkler@intel.com>;

>Usyskin, Alexander <alexander.usyskin@intel.com>

>Cc: Vivi, Rodrigo <rodrigo.vivi@intel.com>

>Subject: [PATCH v3 16/40] misc/mei/hdcp: Verify M_prime

>

>Request to ME to verify the M_Prime received from the HDCP sink.

>

>ME FW will calculate the M and compare with M_prime received as part of

>RepeaterAuth_Stream_Ready, which is HDCP2.2 protocol msg.

>

>On successful completion of this stage, downstream propagation of the stream

>management info is completed.

>

>v2:

>  Rebased.

>v3:

>  cldev is passed as first parameter [Tomas]

>  Redundant comments and cast are removed [Tomas]

>

>Signed-off-by: Ramalingam C <ramalingam.c@intel.com>

>---

> drivers/misc/mei/hdcp/mei_hdcp.c | 79

>++++++++++++++++++++++++++++++++++++++++

> include/linux/mei_hdcp.h         |  8 ++++

> 2 files changed, 87 insertions(+)

>

>diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c

>b/drivers/misc/mei/hdcp/mei_hdcp.c

>index 64fcecfa5b10..68eb5267a8e7 100644

>--- a/drivers/misc/mei/hdcp/mei_hdcp.c

>+++ b/drivers/misc/mei/hdcp/mei_hdcp.c

>@@ -553,6 +553,85 @@ mei_repeater_check_flow_prepare_ack(struct

>mei_cl_device *cldev,  }

>EXPORT_SYMBOL(mei_repeater_check_flow_prepare_ack);

>

>+static inline void reverse_endianness(u8 *dest, size_t dst_sz, u8 *src)


Function with loop ideally should not be inline. 

>+{

>+	u32 index;

>+

>+	if (dest != NULL && dst_sz != 0) {


Good to check for src as well. Also this function will not do anything if these
check fails with caller not even been aware of the failure. Atleast return an
error or make sure no parameter validation happens here and its done by calling
function.

>+		for (index = 0; index < dst_sz && index < sizeof(u32);

>+		     index++) {

>+			dest[dst_sz - index - 1] = src[index];

>+		}

>+	}

>+}

>+

>+/**

>+ * mei_verify_mprime:

>+ *	Function to verify mprime.

>+ *

>+ * @cldev		: Pointer for mei client device

>+ * @data		: Intel HW specific Data

>+ * @stream_ready	: pointer for RepeaterAuth_Stream_Ready message.

>+ *

>+ * Returns 0 on Success, <0 on Failure

>+ */

>+int mei_verify_mprime(struct mei_cl_device *cldev, struct mei_hdcp_data

>*data,

>+		      struct hdcp2_rep_stream_ready *stream_ready) {

>+	struct wired_cmd_repeater_auth_stream_req_in

>+					verify_mprime_in = { { 0 } };

>+	struct wired_cmd_repeater_auth_stream_req_out

>+					verify_mprime_out = { { 0 } };

>+	struct device *dev;

>+	ssize_t byte;

>+

>+	if (!stream_ready || !data)

>+		return -EINVAL;

>+

>+	dev = &cldev->dev;

>+

>+	verify_mprime_in.header.api_version = HDCP_API_VERSION;

>+	verify_mprime_in.header.command_id =

>WIRED_REPEATER_AUTH_STREAM_REQ;

>+	verify_mprime_in.header.status = ME_HDCP_STATUS_SUCCESS;

>+	verify_mprime_in.header.buffer_len =

>+

>	WIRED_CMD_BUF_LEN_REPEATER_AUTH_STREAM_REQ_MIN_IN;

>+

>+	verify_mprime_in.port.integrated_port_type = data->port_type;

>+	verify_mprime_in.port.physical_port = data->port;

>+

>+	memcpy(verify_mprime_in.m_prime, stream_ready->m_prime,


Validate stream_ready->m_prime.

>+	       HDCP_2_2_MPRIME_LEN);

>+	reverse_endianness((u8 *)&verify_mprime_in.seq_num_m,

>+			   HDCP_2_2_SEQ_NUM_LEN, (u8 *)&data-

>>seq_num_m);


>+	memcpy(verify_mprime_in.streams, data->streams,


Validate data->streams.

>+	       (data->k * sizeof(struct hdcp2_streamid_type)));

>+

>+	verify_mprime_in.k = __swab16(data->k);

>+

>+	byte = mei_cldev_send(cldev, (u8 *)&verify_mprime_in,

>+			      sizeof(verify_mprime_in));

>+	if (byte < 0) {

>+		dev_dbg(dev, "mei_cldev_send failed. %d\n", (int)byte);

>+		return byte;

>+	}

>+

>+	byte = mei_cldev_recv(cldev, (u8 *)&verify_mprime_out,

>+			      sizeof(verify_mprime_out));

>+	if (byte < 0) {

>+		dev_dbg(dev, "mei_cldev_recv failed. %d\n", (int)byte);

>+		return byte;

>+	}

>+

>+	if (verify_mprime_out.header.status != ME_HDCP_STATUS_SUCCESS) {

>+		dev_dbg(dev, "ME cmd 0x%08X failed. status: 0x%X\n",

>+			WIRED_REPEATER_AUTH_STREAM_REQ,

>+			verify_mprime_out.header.status);

>+		return -1;

>+	}


Leave a blank line here.

>+	return 0;

>+}

>+EXPORT_SYMBOL(mei_verify_mprime);

>+

> void mei_cldev_state_notify_clients(struct mei_cl_device *cldev, bool enabled)  {

> 	if (enabled)

>diff --git a/include/linux/mei_hdcp.h b/include/linux/mei_hdcp.h index

>46e2dc295d03..dbc216e13f97 100644

>--- a/include/linux/mei_hdcp.h

>+++ b/include/linux/mei_hdcp.h

>@@ -134,6 +134,8 @@ mei_repeater_check_flow_prepare_ack(struct

>mei_cl_device *cldev,

> 				    struct hdcp2_rep_send_receiverid_list

> 							*rep_topology,

> 				    struct hdcp2_rep_send_ack *rep_send_ack);

>+int mei_verify_mprime(struct mei_cl_device *cldev, struct mei_hdcp_data

>*data,

>+		      struct hdcp2_rep_stream_ready *stream_ready);

> #else

> static int mei_cldev_register_notify(struct notifier_block *nb)  { @@ -201,5

>+203,11 @@ mei_repeater_check_flow_prepare_ack(struct mei_cl_device

>*cldev,  {

> 	return -ENODEV;

> }

>+static inline

>+int mei_verify_mprime(struct mei_cl_device *cldev, struct mei_hdcp_data

>*data,

>+		      struct hdcp2_rep_stream_ready *stream_ready) {

>+	return -ENODEV;

>+}

> #endif /* defined (CONFIG_INTEL_MEI_HDCP) */  #endif /* defined

>(_LINUX_MEI_HDCP_H) */

>--

>2.7.4

>

>_______________________________________________

>dri-devel mailing list

>dri-devel@lists.freedesktop.org

>https://lists.freedesktop.org/mailman/listinfo/dri-devel
Ramalingam C May 16, 2018, 4:32 p.m. UTC | #2
On Wednesday 09 May 2018 07:20 PM, Shankar, Uma wrote:
>
>> -----Original Message-----
>> From: dri-devel [mailto:dri-devel-bounces@lists.freedesktop.org] On Behalf Of
>> Ramalingam C
>> Sent: Tuesday, April 3, 2018 7:27 PM
>> To: intel-gfx@lists.freedesktop.org; dri-devel@lists.freedesktop.org;
>> seanpaul@chromium.org; daniel@ffwll.ch; chris@chris-wilson.co.uk;
>> jani.nikula@linux.intel.com; Winkler, Tomas <tomas.winkler@intel.com>;
>> Usyskin, Alexander <alexander.usyskin@intel.com>
>> Cc: Vivi, Rodrigo <rodrigo.vivi@intel.com>
>> Subject: [PATCH v3 16/40] misc/mei/hdcp: Verify M_prime
>>
>> Request to ME to verify the M_Prime received from the HDCP sink.
>>
>> ME FW will calculate the M and compare with M_prime received as part of
>> RepeaterAuth_Stream_Ready, which is HDCP2.2 protocol msg.
>>
>> On successful completion of this stage, downstream propagation of the stream
>> management info is completed.
>>
>> v2:
>>   Rebased.
>> v3:
>>   cldev is passed as first parameter [Tomas]
>>   Redundant comments and cast are removed [Tomas]
>>
>> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
>> ---
>> drivers/misc/mei/hdcp/mei_hdcp.c | 79
>> ++++++++++++++++++++++++++++++++++++++++
>> include/linux/mei_hdcp.h         |  8 ++++
>> 2 files changed, 87 insertions(+)
>>
>> diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c
>> b/drivers/misc/mei/hdcp/mei_hdcp.c
>> index 64fcecfa5b10..68eb5267a8e7 100644
>> --- a/drivers/misc/mei/hdcp/mei_hdcp.c
>> +++ b/drivers/misc/mei/hdcp/mei_hdcp.c
>> @@ -553,6 +553,85 @@ mei_repeater_check_flow_prepare_ack(struct
>> mei_cl_device *cldev,  }
>> EXPORT_SYMBOL(mei_repeater_check_flow_prepare_ack);
>>
>> +static inline void reverse_endianness(u8 *dest, size_t dst_sz, u8 *src)
> Function with loop ideally should not be inline.
Thanks for catching it.
>
>> +{
>> +	u32 index;
>> +
>> +	if (dest != NULL && dst_sz != 0) {
> Good to check for src as well. Also this function will not do anything if these
> check fails with caller not even been aware of the failure. Atleast return an
> error or make sure no parameter validation happens here and its done by calling
> function.
bit rewriting this function. Thanks

--Ram
>
>> +		for (index = 0; index < dst_sz && index < sizeof(u32);
>> +		     index++) {
>> +			dest[dst_sz - index - 1] = src[index];
>> +		}
>> +	}
>> +}
>> +
>> +/**
>> + * mei_verify_mprime:
>> + *	Function to verify mprime.
>> + *
>> + * @cldev		: Pointer for mei client device
>> + * @data		: Intel HW specific Data
>> + * @stream_ready	: pointer for RepeaterAuth_Stream_Ready message.
>> + *
>> + * Returns 0 on Success, <0 on Failure
>> + */
>> +int mei_verify_mprime(struct mei_cl_device *cldev, struct mei_hdcp_data
>> *data,
>> +		      struct hdcp2_rep_stream_ready *stream_ready) {
>> +	struct wired_cmd_repeater_auth_stream_req_in
>> +					verify_mprime_in = { { 0 } };
>> +	struct wired_cmd_repeater_auth_stream_req_out
>> +					verify_mprime_out = { { 0 } };
>> +	struct device *dev;
>> +	ssize_t byte;
>> +
>> +	if (!stream_ready || !data)
>> +		return -EINVAL;
>> +
>> +	dev = &cldev->dev;
>> +
>> +	verify_mprime_in.header.api_version = HDCP_API_VERSION;
>> +	verify_mprime_in.header.command_id =
>> WIRED_REPEATER_AUTH_STREAM_REQ;
>> +	verify_mprime_in.header.status = ME_HDCP_STATUS_SUCCESS;
>> +	verify_mprime_in.header.buffer_len =
>> +
>> 	WIRED_CMD_BUF_LEN_REPEATER_AUTH_STREAM_REQ_MIN_IN;
>> +
>> +	verify_mprime_in.port.integrated_port_type = data->port_type;
>> +	verify_mprime_in.port.physical_port = data->port;
>> +
>> +	memcpy(verify_mprime_in.m_prime, stream_ready->m_prime,
> Validate stream_ready->m_prime.
>
>> +	       HDCP_2_2_MPRIME_LEN);
>> +	reverse_endianness((u8 *)&verify_mprime_in.seq_num_m,
>> +			   HDCP_2_2_SEQ_NUM_LEN, (u8 *)&data-
>>> seq_num_m);
>> +	memcpy(verify_mprime_in.streams, data->streams,
> Validate data->streams.
>
>> +	       (data->k * sizeof(struct hdcp2_streamid_type)));
>> +
>> +	verify_mprime_in.k = __swab16(data->k);
>> +
>> +	byte = mei_cldev_send(cldev, (u8 *)&verify_mprime_in,
>> +			      sizeof(verify_mprime_in));
>> +	if (byte < 0) {
>> +		dev_dbg(dev, "mei_cldev_send failed. %d\n", (int)byte);
>> +		return byte;
>> +	}
>> +
>> +	byte = mei_cldev_recv(cldev, (u8 *)&verify_mprime_out,
>> +			      sizeof(verify_mprime_out));
>> +	if (byte < 0) {
>> +		dev_dbg(dev, "mei_cldev_recv failed. %d\n", (int)byte);
>> +		return byte;
>> +	}
>> +
>> +	if (verify_mprime_out.header.status != ME_HDCP_STATUS_SUCCESS) {
>> +		dev_dbg(dev, "ME cmd 0x%08X failed. status: 0x%X\n",
>> +			WIRED_REPEATER_AUTH_STREAM_REQ,
>> +			verify_mprime_out.header.status);
>> +		return -1;
>> +	}
> Leave a blank line here.
>
>> +	return 0;
>> +}
>> +EXPORT_SYMBOL(mei_verify_mprime);
>> +
>> void mei_cldev_state_notify_clients(struct mei_cl_device *cldev, bool enabled)  {
>> 	if (enabled)
>> diff --git a/include/linux/mei_hdcp.h b/include/linux/mei_hdcp.h index
>> 46e2dc295d03..dbc216e13f97 100644
>> --- a/include/linux/mei_hdcp.h
>> +++ b/include/linux/mei_hdcp.h
>> @@ -134,6 +134,8 @@ mei_repeater_check_flow_prepare_ack(struct
>> mei_cl_device *cldev,
>> 				    struct hdcp2_rep_send_receiverid_list
>> 							*rep_topology,
>> 				    struct hdcp2_rep_send_ack *rep_send_ack);
>> +int mei_verify_mprime(struct mei_cl_device *cldev, struct mei_hdcp_data
>> *data,
>> +		      struct hdcp2_rep_stream_ready *stream_ready);
>> #else
>> static int mei_cldev_register_notify(struct notifier_block *nb)  { @@ -201,5
>> +203,11 @@ mei_repeater_check_flow_prepare_ack(struct mei_cl_device
>> *cldev,  {
>> 	return -ENODEV;
>> }
>> +static inline
>> +int mei_verify_mprime(struct mei_cl_device *cldev, struct mei_hdcp_data
>> *data,
>> +		      struct hdcp2_rep_stream_ready *stream_ready) {
>> +	return -ENODEV;
>> +}
>> #endif /* defined (CONFIG_INTEL_MEI_HDCP) */  #endif /* defined
>> (_LINUX_MEI_HDCP_H) */
>> --
>> 2.7.4
>>
>> _______________________________________________
>> dri-devel mailing list
>> dri-devel@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/dri-devel
diff mbox

Patch

diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c b/drivers/misc/mei/hdcp/mei_hdcp.c
index 64fcecfa5b10..68eb5267a8e7 100644
--- a/drivers/misc/mei/hdcp/mei_hdcp.c
+++ b/drivers/misc/mei/hdcp/mei_hdcp.c
@@ -553,6 +553,85 @@  mei_repeater_check_flow_prepare_ack(struct mei_cl_device *cldev,
 }
 EXPORT_SYMBOL(mei_repeater_check_flow_prepare_ack);
 
+static inline void reverse_endianness(u8 *dest, size_t dst_sz, u8 *src)
+{
+	u32 index;
+
+	if (dest != NULL && dst_sz != 0) {
+		for (index = 0; index < dst_sz && index < sizeof(u32);
+		     index++) {
+			dest[dst_sz - index - 1] = src[index];
+		}
+	}
+}
+
+/**
+ * mei_verify_mprime:
+ *	Function to verify mprime.
+ *
+ * @cldev		: Pointer for mei client device
+ * @data		: Intel HW specific Data
+ * @stream_ready	: pointer for RepeaterAuth_Stream_Ready message.
+ *
+ * Returns 0 on Success, <0 on Failure
+ */
+int mei_verify_mprime(struct mei_cl_device *cldev, struct mei_hdcp_data *data,
+		      struct hdcp2_rep_stream_ready *stream_ready)
+{
+	struct wired_cmd_repeater_auth_stream_req_in
+					verify_mprime_in = { { 0 } };
+	struct wired_cmd_repeater_auth_stream_req_out
+					verify_mprime_out = { { 0 } };
+	struct device *dev;
+	ssize_t byte;
+
+	if (!stream_ready || !data)
+		return -EINVAL;
+
+	dev = &cldev->dev;
+
+	verify_mprime_in.header.api_version = HDCP_API_VERSION;
+	verify_mprime_in.header.command_id = WIRED_REPEATER_AUTH_STREAM_REQ;
+	verify_mprime_in.header.status = ME_HDCP_STATUS_SUCCESS;
+	verify_mprime_in.header.buffer_len =
+			WIRED_CMD_BUF_LEN_REPEATER_AUTH_STREAM_REQ_MIN_IN;
+
+	verify_mprime_in.port.integrated_port_type = data->port_type;
+	verify_mprime_in.port.physical_port = data->port;
+
+	memcpy(verify_mprime_in.m_prime, stream_ready->m_prime,
+	       HDCP_2_2_MPRIME_LEN);
+	reverse_endianness((u8 *)&verify_mprime_in.seq_num_m,
+			   HDCP_2_2_SEQ_NUM_LEN, (u8 *)&data->seq_num_m);
+	memcpy(verify_mprime_in.streams, data->streams,
+	       (data->k * sizeof(struct hdcp2_streamid_type)));
+
+	verify_mprime_in.k = __swab16(data->k);
+
+	byte = mei_cldev_send(cldev, (u8 *)&verify_mprime_in,
+			      sizeof(verify_mprime_in));
+	if (byte < 0) {
+		dev_dbg(dev, "mei_cldev_send failed. %d\n", (int)byte);
+		return byte;
+	}
+
+	byte = mei_cldev_recv(cldev, (u8 *)&verify_mprime_out,
+			      sizeof(verify_mprime_out));
+	if (byte < 0) {
+		dev_dbg(dev, "mei_cldev_recv failed. %d\n", (int)byte);
+		return byte;
+	}
+
+	if (verify_mprime_out.header.status != ME_HDCP_STATUS_SUCCESS) {
+		dev_dbg(dev, "ME cmd 0x%08X failed. status: 0x%X\n",
+			WIRED_REPEATER_AUTH_STREAM_REQ,
+			verify_mprime_out.header.status);
+		return -1;
+	}
+	return 0;
+}
+EXPORT_SYMBOL(mei_verify_mprime);
+
 void mei_cldev_state_notify_clients(struct mei_cl_device *cldev, bool enabled)
 {
 	if (enabled)
diff --git a/include/linux/mei_hdcp.h b/include/linux/mei_hdcp.h
index 46e2dc295d03..dbc216e13f97 100644
--- a/include/linux/mei_hdcp.h
+++ b/include/linux/mei_hdcp.h
@@ -134,6 +134,8 @@  mei_repeater_check_flow_prepare_ack(struct mei_cl_device *cldev,
 				    struct hdcp2_rep_send_receiverid_list
 							*rep_topology,
 				    struct hdcp2_rep_send_ack *rep_send_ack);
+int mei_verify_mprime(struct mei_cl_device *cldev, struct mei_hdcp_data *data,
+		      struct hdcp2_rep_stream_ready *stream_ready);
 #else
 static int mei_cldev_register_notify(struct notifier_block *nb)
 {
@@ -201,5 +203,11 @@  mei_repeater_check_flow_prepare_ack(struct mei_cl_device *cldev,
 {
 	return -ENODEV;
 }
+static inline
+int mei_verify_mprime(struct mei_cl_device *cldev, struct mei_hdcp_data *data,
+		      struct hdcp2_rep_stream_ready *stream_ready)
+{
+	return -ENODEV;
+}
 #endif /* defined (CONFIG_INTEL_MEI_HDCP) */
 #endif /* defined (_LINUX_MEI_HDCP_H) */