Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f26ae6a6 authored by Ramalingam C's avatar Ramalingam C Committed by Daniel Vetter
Browse files

drm/i915: SRM revocation check for HDCP1.4 and 2.2



DRM HDCP SRM revocation check services are used from I915 for HDCP1.4
and 2.2 revocation check during the respective authentication flow.

v2:
  Rebased.
v3:
  %s/*_ksvs_revocated/*_check_ksvs_revoked [Daniel]
  unwanted noise is removed.

Signed-off-by: default avatarRamalingam C <ramalingam.c@intel.com>
Reviewed-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20190507162745.25600-6-ramalingam.c@intel.com
parent 6498bf58
Loading
Loading
Loading
Loading
+38 −7
Original line number Diff line number Diff line
@@ -491,9 +491,11 @@ int intel_hdcp_validate_v_prime(struct intel_digital_port *intel_dig_port,

/* Implements Part 2 of the HDCP authorization procedure */
static
int intel_hdcp_auth_downstream(struct intel_digital_port *intel_dig_port,
			       const struct intel_hdcp_shim *shim)
int intel_hdcp_auth_downstream(struct intel_connector *connector)
{
	struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
	const struct intel_hdcp_shim *shim = connector->hdcp.shim;
	struct drm_device *dev = connector->base.dev;
	u8 bstatus[2], num_downstream, *ksv_fifo;
	int ret, i, tries = 3;

@@ -532,6 +534,11 @@ int intel_hdcp_auth_downstream(struct intel_digital_port *intel_dig_port,
	if (ret)
		goto err;

	if (drm_hdcp_check_ksvs_revoked(dev, ksv_fifo, num_downstream)) {
		DRM_ERROR("Revoked Ksv(s) in ksv_fifo\n");
		return -EPERM;
	}

	/*
	 * When V prime mismatches, DP Spec mandates re-read of
	 * V prime atleast twice.
@@ -558,9 +565,12 @@ int intel_hdcp_auth_downstream(struct intel_digital_port *intel_dig_port,
}

/* Implements Part 1 of the HDCP authorization procedure */
static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port,
			   const struct intel_hdcp_shim *shim)
static int intel_hdcp_auth(struct intel_connector *connector)
{
	struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
	struct intel_hdcp *hdcp = &connector->hdcp;
	struct drm_device *dev = connector->base.dev;
	const struct intel_hdcp_shim *shim = hdcp->shim;
	struct drm_i915_private *dev_priv;
	enum port port;
	unsigned long r0_prime_gen_start;
@@ -626,6 +636,11 @@ static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port,
	if (ret < 0)
		return ret;

	if (drm_hdcp_check_ksvs_revoked(dev, bksv.shim, 1)) {
		DRM_ERROR("BKSV is revoked\n");
		return -EPERM;
	}

	I915_WRITE(PORT_HDCP_BKSVLO(port), bksv.reg[0]);
	I915_WRITE(PORT_HDCP_BKSVHI(port), bksv.reg[1]);

@@ -699,7 +714,7 @@ static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port,
	 */

	if (repeater_present)
		return intel_hdcp_auth_downstream(intel_dig_port, shim);
		return intel_hdcp_auth_downstream(connector);

	DRM_DEBUG_KMS("HDCP is enabled (no repeater present)\n");
	return 0;
@@ -762,7 +777,7 @@ static int _intel_hdcp_enable(struct intel_connector *connector)

	/* Incase of authentication failures, HDCP spec expects reauth. */
	for (i = 0; i < tries; i++) {
		ret = intel_hdcp_auth(conn_to_dig_port(connector), hdcp->shim);
		ret = intel_hdcp_auth(connector);
		if (!ret) {
			hdcp->hdcp_encrypted = true;
			return 0;
@@ -1161,6 +1176,7 @@ static int hdcp2_authentication_key_exchange(struct intel_connector *connector)
{
	struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
	struct intel_hdcp *hdcp = &connector->hdcp;
	struct drm_device *dev = connector->base.dev;
	union {
		struct hdcp2_ake_init ake_init;
		struct hdcp2_ake_send_cert send_cert;
@@ -1195,6 +1211,12 @@ static int hdcp2_authentication_key_exchange(struct intel_connector *connector)

	hdcp->is_repeater = HDCP_2_2_RX_REPEATER(msgs.send_cert.rx_caps[2]);

	if (drm_hdcp_check_ksvs_revoked(dev, msgs.send_cert.cert_rx.receiver_id,
					1)) {
		DRM_ERROR("Receiver ID is revoked\n");
		return -EPERM;
	}

	/*
	 * Here msgs.no_stored_km will hold msgs corresponding to the km
	 * stored also.
@@ -1347,13 +1369,14 @@ int hdcp2_authenticate_repeater_topology(struct intel_connector *connector)
{
	struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
	struct intel_hdcp *hdcp = &connector->hdcp;
	struct drm_device *dev = connector->base.dev;
	union {
		struct hdcp2_rep_send_receiverid_list recvid_list;
		struct hdcp2_rep_send_ack rep_ack;
	} msgs;
	const struct intel_hdcp_shim *shim = hdcp->shim;
	u32 seq_num_v, device_cnt;
	u8 *rx_info;
	u32 seq_num_v;
	int ret;

	ret = shim->read_2_2_msg(intel_dig_port, HDCP_2_2_REP_SEND_RECVID_LIST,
@@ -1379,6 +1402,14 @@ int hdcp2_authenticate_repeater_topology(struct intel_connector *connector)
		return -EINVAL;
	}

	device_cnt = HDCP_2_2_DEV_COUNT_HI(rx_info[0]) << 4 ||
			HDCP_2_2_DEV_COUNT_LO(rx_info[1]);
	if (drm_hdcp_check_ksvs_revoked(dev, msgs.recvid_list.receiver_ids,
					device_cnt)) {
		DRM_ERROR("Revoked receiver ID(s) is in list\n");
		return -EPERM;
	}

	ret = hdcp2_verify_rep_topology_prepare_ack(connector,
						    &msgs.recvid_list,
						    &msgs.rep_ack);