@@ -119,6 +119,95 @@ int mei_initiate_hdcp2_session(struct mei_hdcp_data *data,
}
EXPORT_SYMBOL(mei_initiate_hdcp2_session);
+/**
+ * mei_verify_receiver_cert_prepare_km:
+ * Function to verify the Receiver Certificate AKE_Send_Cert
+ * and prepare AKE_Stored_Km or AKE_No_Stored_Km
+ *
+ * @data : Intel HW specific Data
+ * @rx_cert : Pointer for AKE_Send_Cert
+ * @km_stored : Pointer for pairing status flag
+ * @ek_pub_km : Pointer for output msg
+ * @msg_sz : Pointer for size of AKE_XXXXX_Km
+ *
+ * Returns 0 on Success, <0 on Failure
+ */
+int
+mei_verify_receiver_cert_prepare_km(struct mei_hdcp_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 } };
+ enum me_hdcp_status status;
+ struct device *dev;
+ ssize_t byte;
+
+ if (!data || !rx_cert || !km_stored || !ek_pub_km || !msg_sz)
+ return -EINVAL;
+
+ /* check for the mei_device enabled or not */
+ if (!mei_cldev_active_and_enabled(data->cldev))
+ return -ENODEV;
+
+ dev = &data->cldev->dev;
+
+ /* Fill header details */
+ 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;
+
+ /* Fill the data */
+ verify_rxcert_in.port.integrated_port_type = data->port_type;
+ verify_rxcert_in.port.physical_port = data->port;
+
+ memcpy(&verify_rxcert_in.cert_rx, &rx_cert->cert_rx,
+ sizeof(rx_cert->cert_rx));
+ memcpy(verify_rxcert_in.r_rx, &rx_cert->r_rx, sizeof(rx_cert->r_rx));
+ memcpy(verify_rxcert_in.rx_caps, rx_cert->rx_caps, HDCP_2_2_RXCAPS_LEN);
+
+ /* Request to ME */
+ byte = mei_cldev_send(data->cldev, (u8 *)&verify_rxcert_in,
+ sizeof(verify_rxcert_in));
+ if (byte < 0) {
+ dev_err(dev, "mei_cldev_send failed: %d\n", (int)byte);
+ return byte;
+ }
+
+ /* Response from ME */
+ byte = mei_cldev_recv(data->cldev, (u8 *)&verify_rxcert_out,
+ sizeof(verify_rxcert_out));
+ if (byte < 0) {
+ dev_err(dev, "mei_cldev_recv failed: %d\n", (int)byte);
+ return byte;
+ }
+
+ status = (enum me_hdcp_status)verify_rxcert_out.header.status;
+ if (status != ME_HDCP_STATUS_SUCCESS) {
+ dev_err(dev, "ME cmd 0x%08X Failed. Status: 0x%X\n",
+ WIRED_VERIFY_RECEIVER_CERT, status);
+ return -1;
+ }
+
+ *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;
+}
+EXPORT_SYMBOL(mei_verify_receiver_cert_prepare_km);
+
static int mei_hdcp_probe(struct mei_cl_device *cldev,
const struct mei_cl_device_id *id)
{
@@ -105,6 +105,12 @@ void mei_hdcp_cldev_put_reference(struct mei_cl_device *cldev);
int mei_initiate_hdcp2_session(struct mei_hdcp_data *data,
struct hdcp2_ake_init *ake_data);
+int
+mei_verify_receiver_cert_prepare_km(struct mei_hdcp_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);
#else
static inline
int mei_hdcp_cldev_get_reference(void *client_data,
@@ -125,5 +131,14 @@ int mei_initiate_hdcp2_session(struct mei_hdcp_data *data,
{
return -ENODEV;
}
+static inline int
+mei_verify_receiver_cert_prepare_km(struct mei_hdcp_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)
+{
+ return -ENODEV;
+}
#endif /* defined (CONFIG_INTEL_MEI_HDCP) */
#endif /* defined (_LINUX_MEI_HDCP_H) */
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. Signed-off-by: Ramalingam C <ramalingam.c@intel.com> --- drivers/misc/mei/hdcp/mei_hdcp.c | 89 ++++++++++++++++++++++++++++++++++++++++ include/linux/mei_hdcp.h | 15 +++++++ 2 files changed, 104 insertions(+)