aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
authorRamalingam C <ramalingam.c@intel.com>2019-02-21 23:41:59 +0530
committerDaniel Vetter <daniel.vetter@ffwll.ch>2019-02-25 17:02:01 +0100
commit39b71c2baa4ff5877f9de47f192db978769f2ac5 (patch)
tree102cdd455a5b5cff31bae3942b6a5a3aa3dfbeae /drivers/misc
parentmisc/mei/hdcp: Initiate Wired HDCP2.2 Tx Session (diff)
downloadlinux-dev-39b71c2baa4ff5877f9de47f192db978769f2ac5.tar.xz
linux-dev-39b71c2baa4ff5877f9de47f192db978769f2ac5.zip
misc/mei/hdcp: Verify Receiver Cert and prepare km
Requests for verification for receiver certification and also the preparation for next AKE auth message with km. On Success ME FW validate the HDCP2.2 receivers certificate and do the revocation check on the receiver ID. AKE_Stored_Km will be prepared if the receiver is already paired, else AKE_No_Stored_Km will be prepared. Here AKE_Stored_Km and AKE_No_Stored_Km are HDCP2.2 protocol msgs. v2: Rebased. v3: cldev is passed as first parameter [Tomas] Redundant comments and cast are removed [Tomas] v4: %zd is used for ssize_t [Alexander] %s/return -1/return -EIO [Alexander] v5: Rebased. v6: Collected the Rb-ed by. Rebasing. v7: Adjust to the new mei interface. Fix for Kdoc. v8: K-Doc Addition. [Tomas] memcpy for const length. v9: renamed func as mei_hdcp_* [Tomas] Inline function is defined for DDI index [Tomas] v10: Fixed the conversion of u8 to bool [Tomas] K-Doc fix [Tomas] v11: Rebased. Signed-off-by: Ramalingam C <ramalingam.c@intel.com> Reviewed-by: Uma Shankar <uma.shankar@intel.com> Acked-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: https://patchwork.freedesktop.org/patch/msgid/1550772730-23280-6-git-send-email-ramalingam.c@intel.com
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/mei/hdcp/mei_hdcp.c83
1 files changed, 82 insertions, 1 deletions
diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c b/drivers/misc/mei/hdcp/mei_hdcp.c
index e2587f8e8b94..fc2a5ce8b156 100644
--- a/drivers/misc/mei/hdcp/mei_hdcp.c
+++ b/drivers/misc/mei/hdcp/mei_hdcp.c
@@ -102,11 +102,92 @@ mei_hdcp_initiate_session(struct device *dev, struct hdcp_port_data *data,
return 0;
}
+/**
+ * mei_hdcp_verify_receiver_cert_prepare_km() - Verify the Receiver Certificate
+ * AKE_Send_Cert and prepare AKE_Stored_Km/AKE_No_Stored_Km
+ * @dev: device corresponding to the mei_cl_device
+ * @data: Intel HW specific hdcp data
+ * @rx_cert: AKE_Send_Cert for verification
+ * @km_stored: Pairing status flag output
+ * @ek_pub_km: AKE_Stored_Km/AKE_No_Stored_Km output msg
+ * @msg_sz : size of AKE_XXXXX_Km output msg
+ *
+ * Return: 0 on Success, <0 on Failure
+ */
+static int
+mei_hdcp_verify_receiver_cert_prepare_km(struct device *dev,
+ struct hdcp_port_data *data,
+ struct hdcp2_ake_send_cert *rx_cert,
+ bool *km_stored,
+ struct hdcp2_ake_no_stored_km
+ *ek_pub_km,
+ size_t *msg_sz)
+{
+ struct wired_cmd_verify_receiver_cert_in verify_rxcert_in = { { 0 } };
+ struct wired_cmd_verify_receiver_cert_out verify_rxcert_out = { { 0 } };
+ struct mei_cl_device *cldev;
+ ssize_t byte;
+
+ if (!dev || !data || !rx_cert || !km_stored || !ek_pub_km || !msg_sz)
+ return -EINVAL;
+
+ cldev = to_mei_cl_device(dev);
+
+ verify_rxcert_in.header.api_version = HDCP_API_VERSION;
+ verify_rxcert_in.header.command_id = WIRED_VERIFY_RECEIVER_CERT;
+ verify_rxcert_in.header.status = ME_HDCP_STATUS_SUCCESS;
+ verify_rxcert_in.header.buffer_len =
+ WIRED_CMD_BUF_LEN_VERIFY_RECEIVER_CERT_IN;
+
+ verify_rxcert_in.port.integrated_port_type = data->port_type;
+ verify_rxcert_in.port.physical_port = mei_get_ddi_index(data->port);
+
+ verify_rxcert_in.cert_rx = rx_cert->cert_rx;
+ memcpy(verify_rxcert_in.r_rx, &rx_cert->r_rx, HDCP_2_2_RRX_LEN);
+ memcpy(verify_rxcert_in.rx_caps, rx_cert->rx_caps, HDCP_2_2_RXCAPS_LEN);
+
+ byte = mei_cldev_send(cldev, (u8 *)&verify_rxcert_in,
+ sizeof(verify_rxcert_in));
+ if (byte < 0) {
+ dev_dbg(dev, "mei_cldev_send failed: %zd\n", byte);
+ return byte;
+ }
+
+ byte = mei_cldev_recv(cldev, (u8 *)&verify_rxcert_out,
+ sizeof(verify_rxcert_out));
+ if (byte < 0) {
+ dev_dbg(dev, "mei_cldev_recv failed: %zd\n", byte);
+ return byte;
+ }
+
+ if (verify_rxcert_out.header.status != ME_HDCP_STATUS_SUCCESS) {
+ dev_dbg(dev, "ME cmd 0x%08X Failed. Status: 0x%X\n",
+ WIRED_VERIFY_RECEIVER_CERT,
+ verify_rxcert_out.header.status);
+ return -EIO;
+ }
+
+ *km_stored = !!verify_rxcert_out.km_stored;
+ if (verify_rxcert_out.km_stored) {
+ ek_pub_km->msg_id = HDCP_2_2_AKE_STORED_KM;
+ *msg_sz = sizeof(struct hdcp2_ake_stored_km);
+ } else {
+ ek_pub_km->msg_id = HDCP_2_2_AKE_NO_STORED_KM;
+ *msg_sz = sizeof(struct hdcp2_ake_no_stored_km);
+ }
+
+ memcpy(ek_pub_km->e_kpub_km, &verify_rxcert_out.ekm_buff,
+ sizeof(verify_rxcert_out.ekm_buff));
+
+ return 0;
+}
+
static const __attribute__((unused))
struct i915_hdcp_component_ops mei_hdcp_ops = {
.owner = THIS_MODULE,
.initiate_hdcp2_session = mei_hdcp_initiate_session,
- .verify_receiver_cert_prepare_km = NULL,
+ .verify_receiver_cert_prepare_km =
+ mei_hdcp_verify_receiver_cert_prepare_km,
.verify_hprime = NULL,
.store_pairing_info = NULL,
.initiate_locality_check = NULL,