Skip to content

Commit

Permalink
drm/i915: SRM revocation check for HDCP1.4 and 2.2
Browse files Browse the repository at this point in the history
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: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20190507162745.25600-6-ramalingam.c@intel.com
  • Loading branch information
Ramalingam C authored and Daniel Vetter committed May 9, 2019
1 parent 6498bf5 commit f26ae6a
Showing 1 changed file with 38 additions and 7 deletions.
45 changes: 38 additions & 7 deletions drivers/gpu/drm/i915/intel_hdcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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.
Expand All @@ -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;
Expand Down Expand Up @@ -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]);

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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,
Expand All @@ -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);
Expand Down

0 comments on commit f26ae6a

Please sign in to comment.