Add 'qcom/opensource/securemsm-kernel/' from commit 'a6005ceed271246683596608e4c56b4d921fb363'

git-subtree-dir: qcom/opensource/securemsm-kernel
git-subtree-mainline: 46e9caf0d0
git-subtree-split: a6005ceed2
Change-Id:
repo: https://git.codelinaro.org/clo/la/platform/vendor/qcom/opensource/securemsm-kernel
tag: LA.VENDOR.14.3.0.r1-17300-lanai.QSSI15.0
This commit is contained in:
David Wronek
2024-10-06 16:45:20 +02:00
92 changed files with 45193 additions and 0 deletions

View File

@@ -0,0 +1,123 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#pragma once
// AUTOGENERATED FILE: DO NOT EDIT
#include <linux/types.h>
#include "smcinvoke_object.h"
#define HDCP1_PROVISION 0
#define HDCP1_VERIFY 1
#define HDCP1_SET_ENCRYPTION 2
#define HDCP1_SET_ENCRYPTION_V2 3
#define HDCP1_SET_KEY 4
#define HDCP1_SET_KEY_V2 5
#define HDCP1_SET_MODE 6
static inline int32_t hdcp1_release(struct Object self)
{
return Object_invoke(self, Object_OP_release, 0, 0);
}
static inline int32_t hdcp1_retain(struct Object self)
{
return Object_invoke(self, Object_OP_retain, 0, 0);
}
static inline int32_t hdcp1_provision(struct Object self, uint32_t keyFormat_val,
const void *key_ptr, size_t key_len,
const void *dps_ptr, size_t dps_len)
{
union ObjectArg a[3] = {{{0, 0}}};
a[0].b = (struct ObjectBuf) {&keyFormat_val, sizeof(uint32_t)};
a[1].bi = (struct ObjectBufIn) {key_ptr, key_len * 1};
a[2].bi = (struct ObjectBufIn) {dps_ptr, dps_len * 1};
return Object_invoke(self, HDCP1_PROVISION, a,
ObjectCounts_pack(3, 0, 0, 0));
}
static inline int32_t hdcp1_verify(struct Object self, uint32_t deviceType_val)
{
union ObjectArg a[1] = {{{0, 0}}};
a[0].b = (struct ObjectBuf) {&deviceType_val, sizeof(uint32_t)};
return Object_invoke(self, HDCP1_VERIFY, a,
ObjectCounts_pack(1, 0, 0, 0));
}
static inline int32_t hdcp1_set_encryption(struct Object self, uint32_t enable_val)
{
union ObjectArg a[1] = {{{0, 0}}};
a[0].b = (struct ObjectBuf) {&enable_val, sizeof(uint32_t)};
return Object_invoke(self, HDCP1_SET_ENCRYPTION, a,
ObjectCounts_pack(1, 0, 0, 0));
}
static inline int32_t hdcp1_set_encryption_v2(struct Object self, uint32_t enable_val,
uint32_t deviceType_val)
{
union ObjectArg a[1] = {{{0, 0}}};
struct {
uint32_t m_enable;
uint32_t m_deviceType;
} i;
a[0].b = (struct ObjectBuf) {&i, 8};
i.m_enable = enable_val;
i.m_deviceType = deviceType_val;
return Object_invoke(self, HDCP1_SET_ENCRYPTION_V2, a,
ObjectCounts_pack(1, 0, 0, 0));
}
static inline int32_t hdcp1_set_key(struct Object self, void *ksv_ptr, size_t ksv_len,
size_t *ksv_lenout)
{
union ObjectArg a[1] = {{{0, 0}}};
int32_t result = 0;
a[0].b = (struct ObjectBuf) {ksv_ptr, ksv_len * 1};
result = Object_invoke(self, HDCP1_SET_KEY, a,
ObjectCounts_pack(0, 1, 0, 0));
*ksv_lenout = a[0].b.size / 1;
return result;
}
static inline int32_t hdcp1_set_key_v2(struct Object self, void *ksv_ptr,
size_t ksv_len, size_t *ksv_lenout,
uint32_t deviceType_val)
{
union ObjectArg a[2] = {{{0, 0}}};
int32_t result = 0;
a[1].b = (struct ObjectBuf) {ksv_ptr, ksv_len * 1};
a[0].b = (struct ObjectBuf) {&deviceType_val, sizeof(uint32_t)};
result = Object_invoke(self, HDCP1_SET_KEY_V2, a,
ObjectCounts_pack(1, 1, 0, 0));
*ksv_lenout = a[1].b.size / 1;
return result;
}
static inline int32_t hdcp1_set_mode(struct Object self, int32_t mode_val)
{
union ObjectArg a[1] = {{{0, 0}}};
a[0].b = (struct ObjectBuf) {&mode_val, sizeof(int32_t)};
return Object_invoke(self, HDCP1_SET_MODE, a,
ObjectCounts_pack(1, 0, 0, 0));
}

View File

@@ -0,0 +1,27 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#pragma once
// AUTOGENERATED FILE: DO NOT EDIT
#include <linux/types.h>
#include "smcinvoke_object.h"
#define IHDCP1OPS_NOTIFY_TOPOLOGY_CHANGE 0
static inline int32_t hdcp1_ops_release(struct Object self)
{
return Object_invoke(self, Object_OP_release, 0, 0);
}
static inline int32_t hdcp1_ops_retain(struct Object self)
{
return Object_invoke(self, Object_OP_retain, 0, 0);
}
static inline int32_t hdcp1_ops_notify_topology_change(struct Object self)
{
return Object_invoke(self, IHDCP1OPS_NOTIFY_TOPOLOGY_CHANGE, 0, 0);
}

View File

@@ -0,0 +1,304 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#pragma once
// AUTOGENERATED FILE: DO NOT EDIT
#include <linux/types.h>
#include "smcinvoke_object.h"
#define HDCP2P2_PROVISION_KEY 0
#define HDCP2P2_VERIFY_KEY 1
#define HDCP2P2_TX_INIT 2
#define HDCP2P2_TX_DEINIT 3
#define HDCP2P2_RCVD_MSG 4
#define HDCP2P2_SEND_TIMEOUT 5
#define HDCP2P2_SET_HW_KEY 6
#define HDCP2P2_QUERY_STREAM_TYPE 7
#define HDCP2P2_INIT 8
#define HDCP2P2_DEINIT 9
#define HDCP2P2_VERSION 10
#define HDCP2P2_SESSION_INIT 11
#define HDCP2P2_SESSION_DEINIT 12
#define HDCP2P2_START_AUTH 13
#define HDCP2P2_SESSION_OPEN_STREAM 14
#define HDCP2P2_SESSION_CLOSE_STREAM 15
#define HDCP2P2_FORCE_ENCRYPTION 16
#define HDCP2P2_DELETE_PAIRING_INFO 17
static inline int32_t hdcp2p2_release(struct Object self)
{
return Object_invoke(self, Object_OP_release, 0, 0);
}
static inline int32_t hdcp2p2_retain(struct Object self)
{
return Object_invoke(self, Object_OP_retain, 0, 0);
}
static inline int32_t hdcp2p2_provision_key(struct Object self, const void *key_ptr,
size_t key_len,
const void *dps_ptr,
size_t dps_len)
{
union ObjectArg a[2] = {{{0, 0}}};
a[0].bi = (struct ObjectBufIn) {key_ptr, key_len * 1};
a[1].bi = (struct ObjectBufIn) {dps_ptr, dps_len * 1};
return Object_invoke(self, HDCP2P2_PROVISION_KEY, a,
ObjectCounts_pack(2, 0, 0, 0));
}
static inline int32_t hdcp2p2_verify_key(struct Object self)
{
return Object_invoke(self, HDCP2P2_VERIFY_KEY, 0, 0);
}
static inline int32_t hdcp2p2_tx_init(struct Object self, uint32_t sessionid_val,
uint32_t *ctxhandle_ptr)
{
union ObjectArg a[2] = {{{0, 0}}};
a[0].b = (struct ObjectBuf) {&sessionid_val, sizeof(uint32_t)};
a[1].b = (struct ObjectBuf) {ctxhandle_ptr, sizeof(uint32_t)};
return Object_invoke(self, HDCP2P2_TX_INIT, a,
ObjectCounts_pack(1, 1, 0, 0));
}
static inline int32_t hdcp2p2_tx_deinit(struct Object self, uint32_t ctxhandle_val)
{
union ObjectArg a[1] = {{{0, 0}}};
a[0].b = (struct ObjectBuf) {&ctxhandle_val, sizeof(uint32_t)};
return Object_invoke(self, HDCP2P2_TX_DEINIT, a,
ObjectCounts_pack(1, 0, 0, 0));
}
static inline int32_t hdcp2p2_rcvd_msg(
struct Object self, const void *reqMsg_ptr, size_t reqMsg_len,
uint32_t ctxhandle_val, void *resMsg_ptr, size_t resMsg_len,
size_t *resMsg_lenout, uint32_t *timeout_ptr, uint32_t *flag_ptr, uint32_t *state_ptr)
{
union ObjectArg a[4] = {{{0, 0}}};
int32_t result = 0;
struct {
uint32_t m_timeout;
uint32_t m_flag;
uint32_t m_state;
} o = {0, 0, 0};
a[2].b = (struct ObjectBuf) {&o, 12};
a[0].bi = (struct ObjectBufIn) {reqMsg_ptr, reqMsg_len * 1};
a[1].b = (struct ObjectBuf) {&ctxhandle_val, sizeof(uint32_t)};
a[3].b = (struct ObjectBuf) {resMsg_ptr, resMsg_len * 1};
result = Object_invoke(self, HDCP2P2_RCVD_MSG, a,
ObjectCounts_pack(2, 2, 0, 0));
*resMsg_lenout = a[3].b.size / 1;
*timeout_ptr = o.m_timeout;
*flag_ptr = o.m_flag;
*state_ptr = o.m_state;
return result;
}
static inline int32_t hdcp2p2_send_timeout(struct Object self, uint32_t ctxhandle_val,
void *resMsg_ptr, size_t resMsg_len,
size_t *resMsg_lenout,
uint32_t *timeout_ptr)
{
union ObjectArg a[3] = {{{0, 0}}};
int32_t result = 0;
a[0].b = (struct ObjectBuf) {&ctxhandle_val, sizeof(uint32_t)};
a[1].b = (struct ObjectBuf) {resMsg_ptr, resMsg_len * 1};
a[2].b = (struct ObjectBuf) {timeout_ptr, sizeof(uint32_t)};
result = Object_invoke(self, HDCP2P2_SEND_TIMEOUT, a,
ObjectCounts_pack(1, 2, 0, 0));
*resMsg_lenout = a[1].b.size / 1;
return result;
}
static inline int32_t hdcp2p2_set_hw_key(struct Object self, uint32_t ctxhandle_val)
{
union ObjectArg a[1] = {{{0, 0}}};
a[0].b = (struct ObjectBuf) {&ctxhandle_val, sizeof(uint32_t)};
return Object_invoke(self, HDCP2P2_SET_HW_KEY, a,
ObjectCounts_pack(1, 0, 0, 0));
}
static inline int32_t hdcp2p2_query_stream_type(
struct Object self, uint32_t ctxhandle_val, void *resMsg_ptr, size_t resMsg_len,
size_t *resMsg_lenout, uint32_t *timeout_ptr)
{
union ObjectArg a[3] = {{{0, 0}}};
int32_t result = 0;
a[0].b = (struct ObjectBuf) {&ctxhandle_val, sizeof(uint32_t)};
a[1].b = (struct ObjectBuf) {resMsg_ptr, resMsg_len * 1};
a[2].b = (struct ObjectBuf) {timeout_ptr, sizeof(uint32_t)};
result = Object_invoke(self, HDCP2P2_QUERY_STREAM_TYPE, a,
ObjectCounts_pack(1, 2, 0, 0));
*resMsg_lenout = a[1].b.size / 1;
return result;
}
static inline int32_t hdcp2p2_init(struct Object self, uint32_t clientVersion_val,
uint32_t *appversion_ptr)
{
union ObjectArg a[2] = {{{0, 0}}};
a[0].b = (struct ObjectBuf) {&clientVersion_val, sizeof(uint32_t)};
a[1].b = (struct ObjectBuf) {appversion_ptr, sizeof(uint32_t)};
return Object_invoke(self, HDCP2P2_INIT, a,
ObjectCounts_pack(1, 1, 0, 0));
}
static inline int32_t hdcp2p2_deinit(struct Object self)
{
return Object_invoke(self, HDCP2P2_DEINIT, 0, 0);
}
static inline int32_t hdcp2p2_version(struct Object self, uint32_t *appversion_ptr)
{
union ObjectArg a[1] = {{{0, 0}}};
a[0].b = (struct ObjectBuf) {appversion_ptr, sizeof(uint32_t)};
return Object_invoke(self, HDCP2P2_VERSION, a,
ObjectCounts_pack(0, 1, 0, 0));
}
static inline int32_t hdcp2p2_session_init(struct Object self, uint32_t deviceId_val,
uint32_t *sessionId_ptr)
{
union ObjectArg a[2] = {{{0, 0}}};
a[0].b = (struct ObjectBuf) {&deviceId_val, sizeof(uint32_t)};
a[1].b = (struct ObjectBuf) {sessionId_ptr, sizeof(uint32_t)};
return Object_invoke(self, HDCP2P2_SESSION_INIT, a,
ObjectCounts_pack(1, 1, 0, 0));
}
static inline int32_t hdcp2p2_session_deinit(struct Object self,
uint32_t sessionId_val)
{
union ObjectArg a[1] = {{{0, 0}}};
a[0].b = (struct ObjectBuf) {&sessionId_val, sizeof(uint32_t)};
return Object_invoke(self, HDCP2P2_SESSION_DEINIT, a,
ObjectCounts_pack(1, 0, 0, 0));
}
static inline int32_t hdcp2p2_start_auth(struct Object self, uint32_t ctxhandle_val,
void *resMsg_ptr, size_t resMsg_len,
size_t *resMsg_lenout,
uint32_t *timeout_ptr,
uint32_t *flag_ptr,
uint32_t *tzctxhandle_ptr)
{
union ObjectArg a[3] = {{{0, 0}}};
int32_t result = 0;
struct {
uint32_t m_timeout;
uint32_t m_flag;
uint32_t m_tzctxhandle;
} o = {0, 0, 0};
a[1].b = (struct ObjectBuf) {&o, 12};
a[0].b = (struct ObjectBuf) {&ctxhandle_val, sizeof(uint32_t)};
a[2].b = (struct ObjectBuf) {resMsg_ptr, resMsg_len * 1};
result = Object_invoke(self, HDCP2P2_START_AUTH, a,
ObjectCounts_pack(1, 2, 0, 0));
*resMsg_lenout = a[2].b.size / 1;
*timeout_ptr = o.m_timeout;
*flag_ptr = o.m_flag;
*tzctxhandle_ptr = o.m_tzctxhandle;
return result;
}
static inline int32_t hdcp2p2_session_open_stream(struct Object self,
uint32_t sessionid_val,
uint32_t vcpayloadid_val,
uint32_t stream_number_val,
uint32_t streamMediaType_val,
uint32_t *resStreamId_ptr)
{
union ObjectArg a[2] = {{{0, 0}}};
struct {
uint32_t m_sessionid;
uint32_t m_vcpayloadid;
uint32_t m_stream_number;
uint32_t m_streamMediaType;
} i = {0, 0, 0, 0};
a[0].b = (struct ObjectBuf) {&i, 16};
i.m_sessionid = sessionid_val;
i.m_vcpayloadid = vcpayloadid_val;
i.m_stream_number = stream_number_val;
i.m_streamMediaType = streamMediaType_val;
a[1].b = (struct ObjectBuf) {resStreamId_ptr, sizeof(uint32_t)};
return Object_invoke(self, HDCP2P2_SESSION_OPEN_STREAM, a,
ObjectCounts_pack(1, 1, 0, 0));
}
static inline int32_t hdcp2p2_session_close_stream(struct Object self,
uint32_t sessionid_val,
uint32_t streamId_val)
{
union ObjectArg a[1] = {{{0, 0}}};
struct {
uint32_t m_sessionid;
uint32_t m_streamId;
} i = {0, 0};
a[0].b = (struct ObjectBuf) {&i, 8};
i.m_sessionid = sessionid_val;
i.m_streamId = streamId_val;
return Object_invoke(self, HDCP2P2_SESSION_CLOSE_STREAM, a,
ObjectCounts_pack(1, 0, 0, 0));
}
static inline int32_t hdcp2p2_force_encryption(struct Object self,
uint32_t ctxhandle_val,
uint32_t enable_val)
{
union ObjectArg a[1] = {{{0, 0}}};
struct {
uint32_t m_ctxhandle;
uint32_t m_enable;
} i = {0, 0};
a[0].b = (struct ObjectBuf) {&i, 8};
i.m_ctxhandle = ctxhandle_val;
i.m_enable = enable_val;
return Object_invoke(self, HDCP2P2_FORCE_ENCRYPTION, a,
ObjectCounts_pack(1, 0, 0, 0));
}
static inline int32_t hdcp2p2_delete_pairing_info(struct Object self)
{
return Object_invoke(self, HDCP2P2_DELETE_PAIRING_INFO, 0, 0);
}

View File

@@ -0,0 +1,338 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "hdcp_main.h"
#include "hdcp_qseecom.h"
#include "hdcp_smcinvoke.h"
struct hdcp_ta_interface ta_interface;
static DEFINE_MUTEX(hdcp1_mutex_g);
static DEFINE_MUTEX(hdcp2_mutex_g);
void select_interface(bool use_smcinvoke)
{
if (use_smcinvoke) {
ta_interface.trusted_app_hdcp1_init = &hdcp1_init_smcinvoke;
ta_interface.trusted_app_hdcp1_feature_supported = &hdcp1_feature_supported_smcinvoke;
ta_interface.trusted_app_hdcp1_set_enc = &hdcp1_set_enc_smcinvoke;
ta_interface.trusted_app_hdcp1_ops_notify = &hdcp1_ops_notify_smcinvoke;
ta_interface.trusted_app_hdcp1_start = &hdcp1_start_smcinvoke;
ta_interface.trusted_app_hdcp1_stop = &hdcp1_stop_smcinvoke;
ta_interface.trusted_app_hdcp2_init = &hdcp2_init_smcinvoke;
ta_interface.trusted_app_hdcp2_deinit = &hdcp2_deinit_smcinvoke;
ta_interface.trusted_app_hdcp2_app_start = &hdcp2_app_start_smcinvoke;
ta_interface.trusted_app_hdcp2_app_start_auth = &hdcp2_app_start_auth_smcinvoke;
ta_interface.trusted_app_hdcp2_app_process_msg = &hdcp2_app_process_msg_smcinvoke;
ta_interface.trusted_app_hdcp2_app_enable_encryption = &hdcp2_app_enable_encryption_smcinvoke;
ta_interface.trusted_app_hdcp2_app_timeout = &hdcp2_app_timeout_smcinvoke;
ta_interface.trusted_app_hdcp2_app_query_stream = &hdcp2_app_query_stream_smcinvoke;
ta_interface.trusted_app_hdcp2_app_stop = &hdcp2_app_stop_smcinvoke;
ta_interface.trusted_app_hdcp2_feature_supported = &hdcp2_feature_supported_smcinvoke;
ta_interface.trusted_app_hdcp2_force_encryption = &hdcp2_force_encryption_smcinvoke;
ta_interface.trusted_app_hdcp2_open_stream = &hdcp2_open_stream_smcinvoke;
ta_interface.trusted_app_hdcp2_close_stream = &hdcp2_close_stream_smcinvoke;
ta_interface.trusted_app_hdcp2_update_app_data = &hdcp2_update_app_data_smcinvoke;
} else {
ta_interface.trusted_app_hdcp1_init = &hdcp1_init_qseecom;
ta_interface.trusted_app_hdcp1_feature_supported = &hdcp1_feature_supported_qseecom;
ta_interface.trusted_app_hdcp1_set_enc = &hdcp1_set_enc_qseecom;
ta_interface.trusted_app_hdcp1_ops_notify = &hdcp1_ops_notify_qseecom;
ta_interface.trusted_app_hdcp1_start = &hdcp1_start_qseecom;
ta_interface.trusted_app_hdcp1_stop = &hdcp1_stop_qseecom;
ta_interface.trusted_app_hdcp2_init = &hdcp2_init_qseecom;
ta_interface.trusted_app_hdcp2_deinit = &hdcp2_deinit_qseecom;
ta_interface.trusted_app_hdcp2_app_start = &hdcp2_app_start_qseecom;
ta_interface.trusted_app_hdcp2_app_start_auth = &hdcp2_app_start_auth_qseecom;
ta_interface.trusted_app_hdcp2_app_process_msg = &hdcp2_app_process_msg_qseecom;
ta_interface.trusted_app_hdcp2_app_timeout = &hdcp2_app_timeout_qseecom;
ta_interface.trusted_app_hdcp2_app_enable_encryption = &hdcp2_app_enable_encryption_qseecom;
ta_interface.trusted_app_hdcp2_app_query_stream = &hdcp2_app_query_stream_qseecom;
ta_interface.trusted_app_hdcp2_app_stop = &hdcp2_app_stop_qseecom;
ta_interface.trusted_app_hdcp2_feature_supported = &hdcp2_feature_supported_qseecom;
ta_interface.trusted_app_hdcp2_force_encryption = &hdcp2_force_encryption_qseecom;
ta_interface.trusted_app_hdcp2_open_stream = &hdcp2_open_stream_qseecom;
ta_interface.trusted_app_hdcp2_close_stream = &hdcp2_close_stream_qseecom;
ta_interface.trusted_app_hdcp2_update_app_data = &hdcp2_update_app_data_qseecom;
}
}
int hdcp1_count_ones(u8 *array, u8 len)
{
int i, j, count = 0;
for (i = 0; i < len; i++)
for (j = 0; j < 8; j++)
count += (((array[i] >> j) & 0x1) ? 1 : 0);
return count;
}
int hdcp1_validate_aksv(u32 aksv_msb, u32 aksv_lsb)
{
int const number_of_ones = 20;
u8 aksv[5] = {0};
pr_debug("AKSV=%02x%08x\n", aksv_msb, aksv_lsb);
aksv[0] = aksv_lsb & 0xFF;
aksv[1] = (aksv_lsb >> 8) & 0xFF;
aksv[2] = (aksv_lsb >> 16) & 0xFF;
aksv[3] = (aksv_lsb >> 24) & 0xFF;
aksv[4] = aksv_msb & 0xFF;
/* check there are 20 ones in AKSV */
if (hdcp1_count_ones(aksv, 5) != number_of_ones) {
pr_err("AKSV bit count failed\n");
return -EINVAL;
}
return 0;
}
bool hdcp2_feature_supported(void *data)
{
int ret = 0;
mutex_lock(&hdcp2_mutex_g);
ret = ta_interface.trusted_app_hdcp2_feature_supported(data);
mutex_unlock(&hdcp2_mutex_g);
return ret;
}
EXPORT_SYMBOL_GPL(hdcp2_feature_supported);
int hdcp2_force_encryption(void *ctx, uint32_t enable)
{
int ret = 0;
mutex_lock(&hdcp2_mutex_g);
ret = ta_interface.trusted_app_hdcp2_force_encryption(ctx, enable);
mutex_unlock(&hdcp2_mutex_g);
return ret;
}
EXPORT_SYMBOL_GPL(hdcp2_force_encryption);
int hdcp2_app_comm(void *ctx, enum hdcp2_app_cmd cmd,
struct hdcp2_app_data *app_data)
{
int ret = 0;
uint32_t req_len = 0;
if (!ctx || !app_data) {
pr_err("invalid input\n");
return -EINVAL;
}
req_len = app_data->request.length;
mutex_lock(&hdcp2_mutex_g);
switch (cmd) {
case HDCP2_CMD_START:
ret = ta_interface.trusted_app_hdcp2_app_start(ctx, req_len);
break;
case HDCP2_CMD_START_AUTH:
ret = ta_interface.trusted_app_hdcp2_app_start_auth(ctx, req_len);
break;
case HDCP2_CMD_PROCESS_MSG:
ret = ta_interface.trusted_app_hdcp2_app_process_msg(ctx, req_len);
break;
case HDCP2_CMD_TIMEOUT:
ret = ta_interface.trusted_app_hdcp2_app_timeout(ctx, req_len);
break;
case HDCP2_CMD_EN_ENCRYPTION:
ret = ta_interface.trusted_app_hdcp2_app_enable_encryption(ctx, req_len);
break;
case HDCP2_CMD_QUERY_STREAM:
ret = ta_interface.trusted_app_hdcp2_app_query_stream(ctx, req_len);
break;
case HDCP2_CMD_STOP:
ret = ta_interface.trusted_app_hdcp2_app_stop(ctx);
break;
default:
goto error;
}
if (ret)
goto error;
ret = ta_interface.trusted_app_hdcp2_update_app_data(ctx, app_data);
error:
mutex_unlock(&hdcp2_mutex_g);
return ret;
}
EXPORT_SYMBOL_GPL(hdcp2_app_comm);
int hdcp2_open_stream(void *ctx, uint8_t vc_payload_id, uint8_t stream_number,
uint32_t *stream_id)
{
int ret = 0;
mutex_lock(&hdcp2_mutex_g);
ret = ta_interface.trusted_app_hdcp2_open_stream(ctx, vc_payload_id, stream_number,
stream_id);
mutex_unlock(&hdcp2_mutex_g);
return ret;
}
EXPORT_SYMBOL_GPL(hdcp2_open_stream);
int hdcp2_close_stream(void *ctx, uint32_t stream_id)
{
int ret = 0;
mutex_lock(&hdcp2_mutex_g);
ret = ta_interface.trusted_app_hdcp2_close_stream(ctx, stream_id);
mutex_unlock(&hdcp2_mutex_g);
return ret;
}
EXPORT_SYMBOL_GPL(hdcp2_close_stream);
void *hdcp2_init(u32 device_type)
{
void *data = NULL;
mutex_lock(&hdcp2_mutex_g);
data = ta_interface.trusted_app_hdcp2_init(device_type);
mutex_unlock(&hdcp2_mutex_g);
return data;
}
EXPORT_SYMBOL_GPL(hdcp2_init);
void hdcp2_set_hdcp_key_verify_retries(void *ctx, u32 max_hdcp_key_verify_retries)
{
struct hdcp2_qsee_handle *handle = ctx;
handle->max_hdcp_key_verify_retries = max_hdcp_key_verify_retries;
pr_debug("hdcp2 max_hdcp_key_verify_retries %d\n", handle->max_hdcp_key_verify_retries);
}
EXPORT_SYMBOL_GPL(hdcp2_set_hdcp_key_verify_retries);
void hdcp2_deinit(void *ctx)
{
ta_interface.trusted_app_hdcp2_deinit(ctx);
}
EXPORT_SYMBOL_GPL(hdcp2_deinit);
void *hdcp1_init(void)
{
void *data = NULL;
mutex_lock(&hdcp1_mutex_g);
data = ta_interface.trusted_app_hdcp1_init();
mutex_unlock(&hdcp1_mutex_g);
return data;
}
EXPORT_SYMBOL_GPL(hdcp1_init);
void hdcp1_set_hdcp_key_verify_retries(void *ctx, u32 max_hdcp_key_verify_retries)
{
struct hdcp1_qsee_handle *handle = ctx;
handle->max_hdcp_key_verify_retries = max_hdcp_key_verify_retries;
pr_debug("hdcp1 max_hdcp_key_verify_retries %d\n", handle->max_hdcp_key_verify_retries);
}
EXPORT_SYMBOL_GPL(hdcp1_set_hdcp_key_verify_retries);
void hdcp1_deinit(void *data)
{
kfree(data);
}
EXPORT_SYMBOL_GPL(hdcp1_deinit);
bool hdcp1_feature_supported(void *data)
{
bool supported = false;
mutex_lock(&hdcp1_mutex_g);
supported = ta_interface.trusted_app_hdcp1_feature_supported(data);
mutex_unlock(&hdcp1_mutex_g);
return supported;
}
EXPORT_SYMBOL_GPL(hdcp1_feature_supported);
int hdcp1_set_enc(void *data, bool enable)
{
int ret = 0;
mutex_lock(&hdcp1_mutex_g);
ret = ta_interface.trusted_app_hdcp1_set_enc(data, enable);
mutex_unlock(&hdcp1_mutex_g);
return ret;
}
EXPORT_SYMBOL_GPL(hdcp1_set_enc);
int hdcp1_ops_notify(void *data, void *topo, bool is_authenticated)
{
int ret = 0;
ret = ta_interface.trusted_app_hdcp1_ops_notify(data, topo, is_authenticated);
return ret;
}
EXPORT_SYMBOL_GPL(hdcp1_ops_notify);
int hdcp1_start(void *data, u32 *aksv_msb, u32 *aksv_lsb)
{
int ret = 0;
mutex_lock(&hdcp1_mutex_g);
ret = ta_interface.trusted_app_hdcp1_start(data, aksv_msb, aksv_lsb);
mutex_unlock(&hdcp1_mutex_g);
return ret;
}
EXPORT_SYMBOL_GPL(hdcp1_start);
void hdcp1_stop(void *data)
{
mutex_lock(&hdcp1_mutex_g);
ta_interface.trusted_app_hdcp1_stop(data);
mutex_unlock(&hdcp1_mutex_g);
}
EXPORT_SYMBOL_GPL(hdcp1_stop);
static int __init hdcp_module_init(void)
{
struct device_node *np = NULL;
bool use_smcinvoke = false;
np = of_find_compatible_node(NULL, NULL, "qcom,hdcp");
if (!np) {
/*select qseecom interface as default if hdcp node
*is not present in dtsi
*/
select_interface(use_smcinvoke);
return 0;
}
use_smcinvoke = of_property_read_bool(np, "qcom,use-smcinvoke");
select_interface(use_smcinvoke);
return 0;
}
static void __exit hdcp_module_exit(void)
{
}
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("HDCP driver");
module_init(hdcp_module_init);
module_exit(hdcp_module_exit);

View File

@@ -0,0 +1,113 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __HDCP_MAIN_H__
#define __HDCP_MAIN_H__
#include <linux/cdev.h>
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/hdcp_qseecom.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/sched.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <misc/qseecom_kernel.h>
#define HDCP2P2_APP_NAME "hdcp2p2"
#define HDCP1_APP_NAME "hdcp1"
#define HDCP1OPS_APP_NAME "ops"
#define HDCPSRM_APP_NAME "hdcpsrm"
#define QSEECOM_SBUFF_SIZE 0x1000
#define MAX_REC_ID_LIST_SIZE 160
#define MAX_TX_MESSAGE_SIZE 129
#define MAX_RX_MESSAGE_SIZE 534
#define MAX_TOPOLOGY_ELEMS 32
#define HDCP1_NOTIFY_TOPOLOGY 1
#define HDCP1_AKSV_SIZE 8
#define HDCP_CLIENT_MAKE_VERSION(maj, min, patch) \
((((maj)&0xFF) << 16) | (((min)&0xFF) << 8) | ((patch)&0xFF))
#define HCDP_TXMTR_GET_MAJOR_VERSION(v) (((v) >> 16) & 0xFF)
#define HCDP_TXMTR_GET_MINOR_VERSION(v) (((v) >> 8) & 0xFF)
#define HCDP_TXMTR_GET_PATCH_VERSION(v) ((v)&0xFF)
#define HDCP_CLIENT_MAJOR_VERSION 2
#define HDCP_CLIENT_MINOR_VERSION 1
#define HDCP_CLIENT_PATCH_VERSION 0
#define HDCP_SUCCESS 0
/* Wait 200ms after authentication */
#define SLEEP_FORCE_ENCRYPTION_MS 200
/* Error code when Qseecomd is not up at boot time */
#define QSEECOMD_ERROR -4103
/* Wait for 100ms on every retry to check if Qseecomd is up */
#define SLEEP_QSEECOMD_WAIT_MS 100
#define SLEEP_SET_HW_KEY_MS 300
/* flags set by tz in response message */
#define HDCP_TXMTR_SUBSTATE_INIT 0
#define HDCP_TXMTR_SUBSTATE_WAITING_FOR_RECIEVERID_LIST 1
#define HDCP_TXMTR_SUBSTATE_PROCESSED_RECIEVERID_LIST 2
#define HDCP_TXMTR_SUBSTATE_WAITING_FOR_STREAM_READY_MESSAGE 3
#define HDCP_TXMTR_SUBSTATE_REPEATER_AUTH_COMPLETE 4
enum hdcp_state {
HDCP_STATE_INIT = 0x00,
HDCP_STATE_APP_LOADED = 0x01,
HDCP_STATE_SESSION_INIT = 0x02,
HDCP_STATE_TXMTR_INIT = 0x04,
HDCP_STATE_AUTHENTICATED = 0x08,
HDCP_STATE_ERROR = 0x10
};
struct hdcp_ta_interface
{
void *(*trusted_app_hdcp1_init)(void);
bool (*trusted_app_hdcp1_feature_supported)(void *data);
int (*trusted_app_hdcp1_set_enc)(void *data,bool enable);
int (*trusted_app_hdcp1_ops_notify)(void *data, void *topo,
bool is_authenticated);
int (*trusted_app_hdcp1_start)(void *data, u32 *aksv_msb,
u32 *aksv_lsb);
void (*trusted_app_hdcp1_stop)(void *data);
void *(*trusted_app_hdcp2_init)(u32 device_type);
void (*trusted_app_hdcp2_deinit)(void *ctx);
int (*trusted_app_hdcp2_app_start)(void *ctx, uint32_t req_len);
int (*trusted_app_hdcp2_app_start_auth)(void *ctx, uint32_t req_len);
int (*trusted_app_hdcp2_app_process_msg)(void *ctx, uint32_t req_len);
int (*trusted_app_hdcp2_app_timeout)(void *ctx, uint32_t req_len);
int (*trusted_app_hdcp2_app_enable_encryption)(void *ctx, uint32_t req_len);
int (*trusted_app_hdcp2_app_query_stream)(void *ctx, uint32_t req_len);
int (*trusted_app_hdcp2_app_stop)(void *ctx);
bool (*trusted_app_hdcp2_feature_supported)(void *ctx);
int (*trusted_app_hdcp2_force_encryption)(void *ctx, uint32_t enable);
int (*trusted_app_hdcp2_open_stream)(void *ctx, uint8_t vc_payload_id,
uint8_t stream_number, uint32_t *stream_id);
int (*trusted_app_hdcp2_close_stream)(void *ctx, uint32_t stream_id);
int (*trusted_app_hdcp2_update_app_data)(void *ctx,
struct hdcp2_app_data *app_data);
};
int hdcp1_validate_aksv(u32 aksv_msb, u32 aksv_lsb);
#endif /* __HDCP_MAIN_H__ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,346 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __HDCP_QSEECOM_H__
#define __HDCP_QSEECOM_H__
#include <linux/hdcp_qseecom.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/types.h>
#include "hdcp_main.h"
/*
* @max_hdcp_key_verify_retries - Max number of retries by default set to 0 which
* is equivalent to 0MS. Actual value will be the one
* from the dtsi file.
*/
struct hdcp1_qsee_handle {
struct qseecom_handle *qseecom_handle;
struct qseecom_handle *hdcpops_handle;
bool feature_supported;
uint32_t device_type;
enum hdcp_state hdcp_state;
char *app_name;
uint32_t max_hdcp_key_verify_retries;
};
/*
* If Qseecomd starts late and hdcp key
* verification has already started, qseecomd_down
* flag will be set to true. It will be set to false
* once the Qseecomd is up. Initial assumption is
* that the Qseecomd will start in time.
*/
static bool qseecomd_down;
/*
* @max_hdcp_key_verify_retries - Max number of retries by default set to 0 which
* is equivalent to 0MS. Actual value will be the one
* from the dtsi file.
*/
struct hdcp2_qsee_handle {
struct hdcp2_app_data app_data;
uint32_t tz_ctxhandle;
bool feature_supported;
enum hdcp_state hdcp_state;
struct qseecom_handle *qseecom_handle;
struct qseecom_handle *hdcpsrm_qseecom_handle;
uint32_t session_id;
bool legacy_app;
uint32_t device_type;
char *app_name;
unsigned char *req_buf;
unsigned char *res_buf;
int (*app_init)(struct hdcp2_qsee_handle *handle);
int (*tx_init)(struct hdcp2_qsee_handle *handle);
uint32_t max_hdcp_key_verify_retries;
};
struct hdcp1_key_set_req {
uint32_t commandid;
} __packed;
struct hdcp1_key_set_rsp {
uint32_t commandid;
uint32_t ret;
uint8_t ksv[HDCP1_AKSV_SIZE];
} __packed;
struct hdcp1_ops_notify_req {
uint32_t commandid;
uint32_t device_type;
uint8_t recv_id_list[MAX_REC_ID_LIST_SIZE];
int32_t recv_id_len;
struct hdcp1_topology topology;
bool is_authenticated;
} __packed;
struct hdcp1_ops_notify_rsp {
uint32_t commandid;
uint32_t ret;
} __packed;
struct hdcp1_set_enc_req {
uint32_t commandid;
uint32_t enable;
} __packed;
struct hdcp1_set_enc_rsp {
uint32_t commandid;
uint32_t ret;
} __packed;
struct hdcp1_key_verify_req {
uint32_t commandid;
uint32_t key_type;
} __packed;
struct hdcp1_key_verify_rsp {
uint32_t commandId;
uint32_t ret;
} __packed;
struct hdcp_init_v1_req {
uint32_t commandid;
} __packed;
struct hdcp_init_v1_rsp {
uint32_t status;
uint32_t commandid;
uint32_t ctxhandle;
uint32_t timeout;
uint32_t msglen;
uint8_t message[MAX_TX_MESSAGE_SIZE];
} __packed;
struct hdcp_init_req {
uint32_t commandid;
uint32_t clientversion;
} __packed;
struct hdcp_init_rsp {
uint32_t status;
uint32_t commandid;
uint32_t appversion;
} __packed;
struct hdcp_session_init_req {
uint32_t commandid;
uint32_t deviceid;
} __packed;
struct hdcp_session_init_rsp {
uint32_t status;
uint32_t commandid;
uint32_t sessionid;
} __packed;
struct hdcp_tx_init_v1_req {
uint32_t commandid;
} __packed;
struct hdcp_tx_init_v1_rsp {
uint32_t status;
uint32_t commandid;
uint32_t ctxhandle;
uint32_t timeout;
uint32_t msglen;
uint8_t message[MAX_TX_MESSAGE_SIZE];
} __packed;
struct hdcp_tx_init_req {
uint32_t commandid;
uint32_t sessionid;
} __packed;
struct hdcp_tx_init_rsp {
uint32_t status;
uint32_t commandid;
uint32_t ctxhandle;
} __packed;
struct hdcp_version_req {
uint32_t commandid;
} __packed;
struct hdcp_version_rsp {
uint32_t status;
uint32_t commandId;
uint32_t appversion;
} __packed;
struct hdcp_session_open_stream_req {
uint32_t commandid;
uint32_t sessionid;
uint32_t vcpayloadid;
uint32_t stream_number;
uint32_t streamMediaType;
} __packed;
struct hdcp_session_open_stream_rsp {
uint32_t status;
uint32_t commandid;
uint32_t streamid;
} __packed;
struct hdcp_session_close_stream_req {
uint32_t commandid;
uint32_t sessionid;
uint32_t streamid;
} __packed;
struct hdcp_session_close_stream_rsp {
uint32_t status;
uint32_t commandid;
} __packed;
struct hdcp_force_encryption_req {
uint32_t commandid;
uint32_t ctxhandle;
uint32_t enable;
} __packed;
struct hdcp_force_encryption_rsp {
uint32_t status;
uint32_t commandid;
} __packed;
struct hdcp_tx_deinit_req {
uint32_t commandid;
uint32_t ctxhandle;
} __packed;
struct hdcp_tx_deinit_rsp {
uint32_t status;
uint32_t commandid;
} __packed;
struct hdcp_session_deinit_req {
uint32_t commandid;
uint32_t sessionid;
} __packed;
struct hdcp_session_deinit_rsp {
uint32_t status;
uint32_t commandid;
} __packed;
struct hdcp_deinit_req {
uint32_t commandid;
} __packed;
struct hdcp_deinit_rsp {
uint32_t status;
uint32_t commandid;
} __packed;
struct hdcp_query_stream_type_req {
uint32_t commandid;
uint32_t ctxhandle;
} __packed;
struct hdcp_query_stream_type_rsp {
uint32_t status;
uint32_t commandid;
uint32_t timeout;
uint32_t msglen;
uint8_t msg[MAX_TX_MESSAGE_SIZE];
} __packed;
struct hdcp_set_hw_key_req {
uint32_t commandid;
uint32_t ctxhandle;
} __packed;
struct hdcp_set_hw_key_rsp {
uint32_t status;
uint32_t commandid;
} __packed;
struct hdcp_send_timeout_req {
uint32_t commandid;
uint32_t ctxhandle;
} __packed;
struct hdcp_send_timeout_rsp {
uint32_t status;
uint32_t commandid;
uint32_t timeout;
uint32_t msglen;
uint8_t message[MAX_TX_MESSAGE_SIZE];
} __packed;
struct hdcp_start_auth_req {
uint32_t commandid;
uint32_t ctxHandle;
} __packed;
struct hdcp_start_auth_rsp {
uint32_t status;
uint32_t commandid;
uint32_t ctxhandle;
uint32_t timeout;
uint32_t msglen;
uint8_t message[MAX_TX_MESSAGE_SIZE];
} __packed;
struct hdcp_rcvd_msg_req {
uint32_t commandid;
uint32_t ctxhandle;
uint32_t msglen;
uint8_t msg[MAX_RX_MESSAGE_SIZE];
} __packed;
struct hdcp_rcvd_msg_rsp {
uint32_t status;
uint32_t commandid;
uint32_t state;
uint32_t timeout;
uint32_t flag;
uint32_t msglen;
uint8_t msg[MAX_TX_MESSAGE_SIZE];
} __packed;
struct hdcp_verify_key_req {
uint32_t commandid;
} __packed;
struct hdcp_verify_key_rsp {
uint32_t status;
uint32_t commandId;
} __packed;
#define HDCP1_SET_KEY 202
#define HDCP1_KEY_VERIFY 204
#define HDCP1_SET_ENC 205
/* DP device type */
#define DEVICE_TYPE_DP 0x8002
void *hdcp1_init_qseecom(void);
bool hdcp1_feature_supported_qseecom(void *data);
int hdcp1_set_enc_qseecom(void *data, bool enable);
int hdcp1_ops_notify_qseecom(void *data, void *topo, bool is_authenticated);
int hdcp1_start_qseecom(void *data, u32 *aksv_msb, u32 *aksv_lsb);
void hdcp1_stop_qseecom(void *data);
void *hdcp2_init_qseecom(u32 device_type);
void hdcp2_deinit_qseecom(void *ctx);
int hdcp2_app_start_qseecom(void *ctx, uint32_t req_len);
int hdcp2_app_start_auth_qseecom(void *ctx, uint32_t req_len);
int hdcp2_app_process_msg_qseecom(void *ctx, uint32_t req_len);
int hdcp2_app_timeout_qseecom(void *ctx, uint32_t req_len);
int hdcp2_app_enable_encryption_qseecom(void *ctx, uint32_t req_len);
int hdcp2_app_query_stream_qseecom(void *ctx, uint32_t req_len);
int hdcp2_app_stop_qseecom(void *ctx);
bool hdcp2_feature_supported_qseecom(void *ctx);
int hdcp2_force_encryption_qseecom(void *ctx, uint32_t enable);
int hdcp2_open_stream_qseecom(void *ctx, uint8_t vc_payload_id,
uint8_t stream_number, uint32_t *stream_id);
int hdcp2_close_stream_qseecom(void *ctx, uint32_t stream_id);
int hdcp2_update_app_data_qseecom(void *ctx, struct hdcp2_app_data *app_data);
#endif /* __HDCP_QSEECOM_H__ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,62 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __HDCP_SMCINVOKE_H__
#define __HDCP_SMCINVOKE_H__
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <include/linux/smcinvoke_object.h>
#include "hdcp_main.h"
struct hdcp1_smcinvoke_handle {
struct Object hdcp1_app_obj;
struct Object hdcp1_appcontroller_obj;
struct Object hdcp1ops_app_obj;
struct Object hdcp1ops_appcontroller_obj;
bool feature_supported;
uint32_t device_type;
enum hdcp_state hdcp_state;
};
struct hdcp2_smcinvoke_handle {
struct hdcp2_app_data app_data;
uint32_t tz_ctxhandle;
bool feature_supported;
enum hdcp_state hdcp_state;
struct Object hdcp2_app_obj;
struct Object hdcp2_appcontroller_obj;
struct Object hdcpsrm_app_obj;
struct Object hdcpsrm_appcontroller_obj;
uint32_t session_id;
uint32_t device_type;
};
void *hdcp1_init_smcinvoke(void);
bool hdcp1_feature_supported_smcinvoke(void *data);
int hdcp1_set_enc_smcinvoke(void *data, bool enable);
int hdcp1_ops_notify_smcinvoke(void *data, void *topo, bool is_authenticated);
int hdcp1_start_smcinvoke(void *data, u32 *aksv_msb, u32 *aksv_lsb);
void hdcp1_stop_smcinvoke(void *data);
void *hdcp2_init_smcinvoke(u32 device_type);
void hdcp2_deinit_smcinvoke(void *ctx);
int hdcp2_app_start_smcinvoke(void *ctx, uint32_t req_len);
int hdcp2_app_start_auth_smcinvoke(void *ctx, uint32_t req_len);
int hdcp2_app_process_msg_smcinvoke(void *ctx, uint32_t req_len);
int hdcp2_app_timeout_smcinvoke(void *ctx, uint32_t req_len);
int hdcp2_app_enable_encryption_smcinvoke(void *ctx, uint32_t req_len);
int hdcp2_app_query_stream_smcinvoke(void *ctx, uint32_t req_len);
int hdcp2_app_stop_smcinvoke(void *ctx);
bool hdcp2_feature_supported_smcinvoke(void *ctx);
int hdcp2_force_encryption_smcinvoke(void *ctx, uint32_t enable);
int hdcp2_open_stream_smcinvoke(void *ctx, uint8_t vc_payload_id,
uint8_t stream_number, uint32_t *stream_id);
int hdcp2_close_stream_smcinvoke(void *ctx, uint32_t stream_id);
int hdcp2_update_app_data_smcinvoke(void *ctx, struct hdcp2_app_data *app_data);
#endif /* __HDCP_SMCINVOKE_H__ */