securemsm-kernel: Enable tmecom module compilation
Enable compilation for tmecom-intf_dlkm.ko compilation. Change-Id: I049c769abea1a53160d82f4c85ec49089f485f7e
This commit is contained in:
10
Android.mk
10
Android.mk
@@ -69,3 +69,13 @@ LOCAL_MODULE_DEBUG_ENABLE := true
|
|||||||
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
|
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
|
||||||
include $(DLKM_DIR)/Build_external_kernelmodule.mk
|
include $(DLKM_DIR)/Build_external_kernelmodule.mk
|
||||||
#################################################
|
#################################################
|
||||||
|
#################################################
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
LOCAL_SRC_FILES := $(SSG_SRC_FILES)
|
||||||
|
LOCAL_MODULE := tmecom-intf_dlkm.ko
|
||||||
|
LOCAL_MODULE_KBUILD_NAME := tmecom-intf_dlkm.ko
|
||||||
|
LOCAL_MODULE_TAGS := optional
|
||||||
|
LOCAL_MODULE_DEBUG_ENABLE := true
|
||||||
|
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
|
||||||
|
include $(DLKM_DIR)/Build_external_kernelmodule.mk
|
||||||
|
#################################################
|
||||||
|
|||||||
3
Kbuild
3
Kbuild
@@ -22,3 +22,6 @@ qcrypto-msm_dlkm-objs := crypto-qti/qcrypto.o
|
|||||||
|
|
||||||
obj-$(CONFIG_HDCP_QSEECOM) += hdcp_qseecom_dlkm.o
|
obj-$(CONFIG_HDCP_QSEECOM) += hdcp_qseecom_dlkm.o
|
||||||
hdcp_qseecom_dlkm-objs := hdcp/hdcp_qseecom.o
|
hdcp_qseecom_dlkm-objs := hdcp/hdcp_qseecom.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_MSM_TMECOM_QMP) := tmecom-intf_dlkm.o
|
||||||
|
tmecom-intf_dlkm-objs := tmecom/tmecom.o tmecom/tme_hwkm_master.o
|
||||||
|
|||||||
@@ -5,4 +5,5 @@ export CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=m
|
|||||||
export CONFIG_CRYPTO_DEV_QCRYPTO=m
|
export CONFIG_CRYPTO_DEV_QCRYPTO=m
|
||||||
export CONFIG_SCSI_UFS_CRYPTO=m
|
export CONFIG_SCSI_UFS_CRYPTO=m
|
||||||
export CONFIG_SCSI_UFS_CRYPTO_QTI=m
|
export CONFIG_SCSI_UFS_CRYPTO_QTI=m
|
||||||
export CONFIG_HDCP_QSEECOM=m
|
export CONFIG_HDCP_QSEECOM=m
|
||||||
|
export CONFIG_MSM_TMECOM_QMP=m
|
||||||
|
|||||||
120
linux/tme_hwkm_master.h
Normal file
120
linux/tme_hwkm_master.h
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||||
|
*/
|
||||||
|
#ifndef _TME_HWKM_MASTER_H_
|
||||||
|
#define _TME_HWKM_MASTER_H_
|
||||||
|
|
||||||
|
#include <linux/tme_hwkm_master_defs.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear a Key Table entry.
|
||||||
|
*
|
||||||
|
* @param [in] key_id The ID of the key to clear.
|
||||||
|
* @param [out] err_info Extended error info
|
||||||
|
*
|
||||||
|
* @return 0 if successful, error code otherwise.
|
||||||
|
*/
|
||||||
|
uint32_t tme_hwkm_master_clearkey(uint32_t key_id,
|
||||||
|
struct tme_ext_err_info *err_info);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a random key with an associated policy.
|
||||||
|
*
|
||||||
|
* @param [in] key_id The ID of the key to be generated.
|
||||||
|
* @param [in] policy The policy specifying the key to be generated.
|
||||||
|
* @param [in] cred_slot Credential slot to which this key will be bound.
|
||||||
|
* @param [out] err_info Extended error info
|
||||||
|
*
|
||||||
|
* @return 0 if successful, error code otherwise.
|
||||||
|
*/
|
||||||
|
uint32_t tme_hwkm_master_generatekey(uint32_t key_id,
|
||||||
|
struct tme_key_policy *policy,
|
||||||
|
uint32_t cred_slot,
|
||||||
|
struct tme_ext_err_info *err_info);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Derive a KEY using either HKDF or NIST algorithms.
|
||||||
|
*
|
||||||
|
* @param [in] key_id The ID of the key to be derived.
|
||||||
|
* @param [in] kdf_info Specifies how the key is to be derived
|
||||||
|
* and the properties of the derived key.
|
||||||
|
* @param [in] cred_slot Credential slot to which this key will be bound.
|
||||||
|
* @param [out] err_info Extended error info
|
||||||
|
*
|
||||||
|
* @return 0 if successful, error code otherwise.
|
||||||
|
*/
|
||||||
|
uint32_t tme_hwkm_master_derivekey(uint32_t key_id,
|
||||||
|
struct tme_kdf_spec *kdf_info,
|
||||||
|
uint32_t cred_slot,
|
||||||
|
struct tme_ext_err_info *err_info);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrap a key so that it can be safely moved outside the TME.
|
||||||
|
*
|
||||||
|
* @param [in] kwkey_id Denotes a key, already present in the
|
||||||
|
* Key Table, to be used to secure the target key.
|
||||||
|
* @param [in] targetkey_id Denotes the key to be wrapped.
|
||||||
|
* @param [in] cred_slot Credential slot to which this key is bound.
|
||||||
|
* @param [out] wrapped Buffer for wrapped key output from response
|
||||||
|
* @param [out] err_info Extended error info
|
||||||
|
*
|
||||||
|
* @return 0 if successful, error code otherwise.
|
||||||
|
*/
|
||||||
|
uint32_t tme_hwkm_master_wrapkey(uint32_t key_id,
|
||||||
|
uint32_t targetkey_id,
|
||||||
|
uint32_t cred_slot,
|
||||||
|
struct tme_wrapped_key *wrapped,
|
||||||
|
struct tme_ext_err_info *err_info);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unwrap a key from outside the TME and store in the Key Table.
|
||||||
|
*
|
||||||
|
* @param [in] key_id The ID of the key to be unwrapped.
|
||||||
|
* @param [in] kwkey_id Denotes a key, already present in the
|
||||||
|
* Key Table, to be used to unwrap the key.
|
||||||
|
* @param [in] cred_slot Credential slot to which this key will be bound.
|
||||||
|
* @param [in] wrapped The key to be unwrapped.
|
||||||
|
* @param [out] err_info Extended error info
|
||||||
|
*
|
||||||
|
* @return 0 if successful, error code otherwise.
|
||||||
|
*/
|
||||||
|
uint32_t tme_hwkm_master_unwrapkey(uint32_t key_id,
|
||||||
|
uint32_t kwkey_id,
|
||||||
|
uint32_t cred_slot,
|
||||||
|
struct tme_wrapped_key *wrapped,
|
||||||
|
struct tme_ext_err_info *err_info);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import a plaintext key from outside the TME and store in the Key Table.
|
||||||
|
*
|
||||||
|
* @param [in] key_id The ID of the key to be imported.
|
||||||
|
* @param [in] policy The Key Policy to be associated with the key.
|
||||||
|
* @param [in] keyMaterial The plaintext key material.
|
||||||
|
* @param [in] cred_slot Credential slot to which this key will be bound.
|
||||||
|
* @param [out] err_info Extended error info
|
||||||
|
*
|
||||||
|
* @return 0 if successful, error code otherwise.
|
||||||
|
*/
|
||||||
|
uint32_t tme_hwkm_master_importkey(uint32_t key_id,
|
||||||
|
struct tme_key_policy *policy,
|
||||||
|
struct tme_plaintext_key *key_material,
|
||||||
|
uint32_t cred_slot,
|
||||||
|
struct tme_ext_err_info *err_info);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Broadcast Transport Key to HWKM slaves.
|
||||||
|
*
|
||||||
|
* @param [out] err_info Extended error info
|
||||||
|
*
|
||||||
|
* @return 0 if successful, error code otherwise.
|
||||||
|
*/
|
||||||
|
uint32_t tme_hwkm_master_broadcast_transportkey(
|
||||||
|
struct tme_ext_err_info *err_info);
|
||||||
|
|
||||||
|
#endif /* _TME_HWKM_MASTER_H_ */
|
||||||
|
|
||||||
462
linux/tme_hwkm_master_defs.h
Normal file
462
linux/tme_hwkm_master_defs.h
Normal file
@@ -0,0 +1,462 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||||
|
*/
|
||||||
|
#ifndef _TME_HWKM_MASTER_DEFS_H_
|
||||||
|
#define _TME_HWKM_MASTER_DEFS_H_
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
#define UINT32_C(x) (x ## U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key ID
|
||||||
|
*/
|
||||||
|
/* L1 Key IDs that are Key Table slot numbers */
|
||||||
|
/**< CUS, 512 bits, in fuses */
|
||||||
|
#define TME_KID_CHIP_UNIQUE_SEED 8
|
||||||
|
/**< CRBK, 512 bits, in fuses */
|
||||||
|
#define TME_KID_CHIP_RAND_BASE 9
|
||||||
|
/**< L1 Key derived from L0 slot numbers 0-3 or 4-7 */
|
||||||
|
#define TME_KID_CHIP_FAM_L1 10
|
||||||
|
|
||||||
|
/* Transport Key ID */
|
||||||
|
#define TME_KID_TP 11/**< 528 bits, retained */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* KeyPolicy
|
||||||
|
*/
|
||||||
|
/** Key Policy: 64-bit integer with bit encoded values */
|
||||||
|
struct tme_key_policy {
|
||||||
|
uint32_t low;
|
||||||
|
uint32_t high;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
#define TME_KPHALFBITS 32
|
||||||
|
|
||||||
|
#define TME_KPCOMBINE(lo32, hi32) (((uint64_t)(lo32)) | \
|
||||||
|
(((uint64_t)(hi32)) << TME_KPHALFBITS))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fields in Key Policy low word
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** Key Type: Fundamental crypto algorithm groups */
|
||||||
|
/**< Position of Key Type bits */
|
||||||
|
#define TME_KT_Shift 0
|
||||||
|
/**< Mask for Key Type bits */
|
||||||
|
#define TME_KT_Mask (UINT32_C(0x07) << TME_KT_Shift)
|
||||||
|
/**< Symmetric algorithms */
|
||||||
|
#define TME_KT_Symmetric (UINT32_C(0x00) << TME_KT_Shift)
|
||||||
|
/**< Asymmetric algorithms: ECC */
|
||||||
|
#define TME_KT_Asymmetric_ECC (UINT32_C(0x01) << TME_KT_Shift)
|
||||||
|
/**< Asymmetric algorithms: RSA */
|
||||||
|
#define TME_KT_Asymmetric_RSA (UINT32_C(0x05) << TME_KT_Shift)
|
||||||
|
|
||||||
|
/** Key Length */
|
||||||
|
/**< Position of Key Length bits */
|
||||||
|
#define TME_KL_Shift 3
|
||||||
|
/**< Mask for Key Length bits */
|
||||||
|
#define TME_KL_Mask (UINT32_C(0x0F) << TME_KL_Shift)
|
||||||
|
/**< 64 bits - AES/2TDES */
|
||||||
|
#define TME_KL_64 (UINT32_C(0x00) << TME_KL_Shift)
|
||||||
|
/**< 128 bits - AES/2TDES */
|
||||||
|
#define TME_KL_128 (UINT32_C(0x01) << TME_KL_Shift)
|
||||||
|
/**< 192 bits - AES/3TDES */
|
||||||
|
#define TME_KL_192 (UINT32_C(0x02) << TME_KL_Shift)
|
||||||
|
/**< 224 bits - ECDSA */
|
||||||
|
#define TME_KL_224 (UINT32_C(0x03) << TME_KL_Shift)
|
||||||
|
/**< 256 bits - ECDSA/AES */
|
||||||
|
#define TME_KL_256 (UINT32_C(0x04) << TME_KL_Shift)
|
||||||
|
/**< 384 bits - ECDSA */
|
||||||
|
#define TME_KL_384 (UINT32_C(0x05) << TME_KL_Shift)
|
||||||
|
/**< 448 bits - ECDSA */
|
||||||
|
#define TME_KL_448 (UINT32_C(0x06) << TME_KL_Shift)
|
||||||
|
/**< 512 bits - ECDSA/HMAC/KDF/AES-SIV/AES-XTS */
|
||||||
|
#define TME_KL_512 (UINT32_C(0x07) << TME_KL_Shift)
|
||||||
|
/**< 521 bits - ECDSA/HMAC/KDF */
|
||||||
|
#define TME_KL_521 (UINT32_C(0x08) << TME_KL_Shift)
|
||||||
|
/**< 2048 bits - RSA */
|
||||||
|
#define TME_KL_2048 (UINT32_C(0x09) << TME_KL_Shift)
|
||||||
|
/**< 3072 bits - RSA */
|
||||||
|
#define TME_KL_3072 (UINT32_C(0x0A) << TME_KL_Shift)
|
||||||
|
/**< 4096 bits - RSA */
|
||||||
|
#define TME_KL_4096 (UINT32_C(0x0B) << TME_KL_Shift)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key Profile: Only applicable at present
|
||||||
|
* if Key Type is #TME_KT_Symmetric
|
||||||
|
*/
|
||||||
|
/**< Position of Key Profile bits */
|
||||||
|
#define TME_KP_Shift 7
|
||||||
|
/**< Mask for Key Class bits */
|
||||||
|
#define TME_KP_Mask (UINT32_C(0x07) << TME_KP_Shift)
|
||||||
|
/**< If Key Type is #TME_KT_Symmetric */
|
||||||
|
#define TME_KP_Generic (UINT32_C(0x00) << TME_KP_Shift)
|
||||||
|
/**< If Key Type is #TME_KT_Symmetric (aka KDK) */
|
||||||
|
#define TME_KP_KeyDerivation (UINT32_C(0x01) << TME_KP_Shift)
|
||||||
|
/**< If Key Type is #TME_KT_Symmetric (aka KWK) */
|
||||||
|
#define TME_KP_KWK_STORAGE (UINT32_C(0x02) << TME_KP_Shift)
|
||||||
|
/**< If Key Type is #TME_KT_Symmetric (aka KSK) */
|
||||||
|
#define TME_KP_KWK_SESSION (UINT32_C(0x03) << TME_KP_Shift)
|
||||||
|
/**< If Key Type is #TME_KT_Symmetric (aka TPK) */
|
||||||
|
#define TME_KP_KWK_TRANSPORT (UINT32_C(0x04) << TME_KP_Shift)
|
||||||
|
/**< If Key Type is #TME_KT_Symmetric */
|
||||||
|
#define TME_KP_KWK_XPORT (UINT32_C(0x05) << TME_KP_Shift)
|
||||||
|
/**< If Key Type is not #TME_KT_Symmetric */
|
||||||
|
#define TME_KP_Unused (UINT32_C(0x00) << TME_KP_Shift)
|
||||||
|
|
||||||
|
/** Key Operation: Crypto operations permitted for a key */
|
||||||
|
/**< Position of Key Operation bits */
|
||||||
|
#define TME_KOP_Shift 10
|
||||||
|
/**< Mask for Key Operation bits */
|
||||||
|
#define TME_KOP_Mask (UINT32_C(0x0F) << TME_KOP_Shift)
|
||||||
|
/**< If Key Type is #TME_KT_Symmetric */
|
||||||
|
#define TME_KOP_Encryption (UINT32_C(0x01) << TME_KOP_Shift)
|
||||||
|
/**< If Key Type is #TME_KT_Symmetric */
|
||||||
|
#define TME_KOP_Decryption (UINT32_C(0x02) << TME_KOP_Shift)
|
||||||
|
/**< If Key Type is #TME_KT_Symmetric */
|
||||||
|
#define TME_KOP_MAC (UINT32_C(0x04) << TME_KOP_Shift)
|
||||||
|
/**< If Key Type is #TME_KT_Symmetric */
|
||||||
|
#define TME_KOP_NISTDerive (UINT32_C(0x04) << TME_KOP_Shift)
|
||||||
|
/**< If Key Type is #TME_KT_Symmetric */
|
||||||
|
#define TME_KOP_HKDFExtract (UINT32_C(0x08) << TME_KOP_Shift)
|
||||||
|
/**< If Key Type is #TME_KT_Symmetric */
|
||||||
|
#define TME_KOP_HKDFExpand (UINT32_C(0x09) << TME_KOP_Shift)
|
||||||
|
/**< If Key Type is #TME_KT_Asymmetric_ECC */
|
||||||
|
#define TME_KOP_ECDSASign (UINT32_C(0x01) << TME_KOP_Shift)
|
||||||
|
/**< If Key Type is #TME_KT_Asymmetric_ECC */
|
||||||
|
#define TME_KOP_ECDSAVerify (UINT32_C(0x02) << TME_KOP_Shift)
|
||||||
|
/**< If Key Type is #TME_KT_Asymmetric_ECC */
|
||||||
|
#define TME_KOP_ECDHSharedSecret (UINT32_C(0x04) << TME_KOP_Shift)
|
||||||
|
/**< If Key Type is #TME_KT_Asymmetric_RSA */
|
||||||
|
#define TME_KOP_RSAASign (UINT32_C(0x01) << TME_KOP_Shift)
|
||||||
|
/**< If Key Type is #TME_KT_Asymmetric_RSA */
|
||||||
|
#define TME_KOP_RSAAVerify (UINT32_C(0x02) << TME_KOP_Shift)
|
||||||
|
/**< If Key Type is #TME_KT_Asymmetric_RSA */
|
||||||
|
#define TME_KOP_RSAEnc (UINT32_C(0x04) << TME_KOP_Shift)
|
||||||
|
/**< If Key Type is #TME_KT_Asymmetric_RSA */
|
||||||
|
#define TME_KOP_RSADec (UINT32_C(0x08) << TME_KOP_Shift)
|
||||||
|
|
||||||
|
/** Key Algorithm */
|
||||||
|
/**< Position of Key Algorithm bits */
|
||||||
|
#define TME_KAL_Shift 14
|
||||||
|
/**< Mask for Key Algorithm bits */
|
||||||
|
#define TME_KAL_Mask (UINT32_C(0x3F) << TME_KAL_Shift)
|
||||||
|
/**< If Key Type is #TME_KT_Symmetric */
|
||||||
|
#define TME_KAL_AES128_ECB (UINT32_C(0x00) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_AES256_ECB (UINT32_C(0x01) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_DES_ECB (UINT32_C(0x02) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_TDES_ECB (UINT32_C(0x03) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_AES128_CBC (UINT32_C(0x04) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_AES256_CBC (UINT32_C(0x05) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_DES_CBC (UINT32_C(0x06) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_TDES_CBC (UINT32_C(0x07) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_AES128_CCM_TC (UINT32_C(0x08) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_AES128_CCM_NTC (UINT32_C(0x09) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_AES256_CCM_TC (UINT32_C(0x0A) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_AES256_CCM_NTC (UINT32_C(0x0B) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_AES256_SIV (UINT32_C(0x0C) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_AES128_CTR (UINT32_C(0x0D) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_AES256_CTR (UINT32_C(0x0E) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_AES128_XTS (UINT32_C(0x0F) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_AES256_XTS (UINT32_C(0x10) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_SHA1_HMAC (UINT32_C(0x11) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_SHA256_HMAC (UINT32_C(0x12) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_AES128_CMAC (UINT32_C(0x13) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_AES256_CMAC (UINT32_C(0x14) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_SHA384_HMAC (UINT32_C(0x15) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_SHA512_HMAC (UINT32_C(0x16) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_AES128_GCM (UINT32_C(0x17) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_AES256_GCM (UINT32_C(0x18) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_KASUMI (UINT32_C(0x19) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_SNOW3G (UINT32_C(0x1A) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_ZUC (UINT32_C(0x1B) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_PRINCE (UINT32_C(0x1C) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_SIPHASH (UINT32_C(0x1D) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_TDES_2KEY_CBC (UINT32_C(0x1E) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_TDES_2KEY_ECB (UINT32_C(0x1F) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_KDF_NIST (UINT32_C(0x20) << TME_KAL_Shift)
|
||||||
|
#define TME_KAL_KDF_HKDF (UINT32_C(0x21) << TME_KAL_Shift)
|
||||||
|
/**< If Key Type is #TME_KT_Asymmetric, Key Subtype is ECC */
|
||||||
|
#define TME_KAL_ECC_ALGO_ECDSA (UINT32_C(0x00) << TME_KAL_Shift)
|
||||||
|
/**< If Key Type is #TME_KT_Asymmetric, Key Subtype is ECC */
|
||||||
|
#define TME_KAL_ECC_ALGO_ECDH (UINT32_C(0x01) << TME_KAL_Shift)
|
||||||
|
/**< If Key Type is #TME_KT_Asymmetric, Key Subtype is ECC */
|
||||||
|
#define TME_KAL_ECC_CURVE_NIST (UINT32_C(0x00) << TME_KAL_Shift)
|
||||||
|
/**< If Key Type is #TME_KT_Asymmetric, Key Subtype is ECC */
|
||||||
|
#define TME_KAL_ECC_CURVE_BPOOL (UINT32_C(0x08) << TME_KAL_Shift)
|
||||||
|
/**< If Key Type is #TME_KT_Asymmetric, Key Subtype is RSA */
|
||||||
|
#define TME_KAL_DSA (UINT32_C(0x00) << TME_KAL_Shift)
|
||||||
|
/**< If Key Type is #TME_KT_Asymmetric, Key Subtype is RSA */
|
||||||
|
#define TME_KAL_DH (UINT32_C(0x01) << TME_KAL_Shift)
|
||||||
|
|
||||||
|
/** Key Security Level */
|
||||||
|
/**< Position of Key Security Level bits */
|
||||||
|
#define TME_KSL_Shift 20
|
||||||
|
/**< Mask for Key Security Level bits */
|
||||||
|
#define TME_KSL_Mask (UINT32_C(0x03) << TME_KSL_Shift)
|
||||||
|
/**< Software Key */
|
||||||
|
#define TME_KSL_SWKey (UINT32_C(0x00) << TME_KSL_Shift)
|
||||||
|
/**< Hardware Managed Key */
|
||||||
|
#define TME_KSL_HWManagedKey (UINT32_C(0x01) << TME_KSL_Shift)
|
||||||
|
/**< Hardware Key */
|
||||||
|
#define TME_KSL_HWKey (UINT32_C(0x02) << TME_KSL_Shift)
|
||||||
|
|
||||||
|
/** Key Destination */
|
||||||
|
/**< Position of Key Destination bits */
|
||||||
|
#define TME_KD_Shift 22
|
||||||
|
/**< Mask for Key Destination bits */
|
||||||
|
#define TME_KD_Mask (UINT32_C(0x0F) << TME_KD_Shift)
|
||||||
|
/**< Master */
|
||||||
|
#define TME_KD_TME_HW (UINT32_C(0x01) << TME_KD_Shift)
|
||||||
|
/**< ICE Slave */
|
||||||
|
#define TME_KD_ICE (UINT32_C(0x02) << TME_KD_Shift)
|
||||||
|
/**< GPCE Slave */
|
||||||
|
#define TME_KD_GPCE (UINT32_C(0x04) << TME_KD_Shift)
|
||||||
|
/**< Modem CE Slave */
|
||||||
|
#define TME_KD_MDM_CE (UINT32_C(0x08) << TME_KD_Shift)
|
||||||
|
|
||||||
|
/** Key Owner */
|
||||||
|
/**< Position of Key Owner bits */
|
||||||
|
#define TME_KO_Shift 26
|
||||||
|
/**< Mask for Key Owner bits */
|
||||||
|
#define TME_KO_Mask (UINT32_C(0x0F) << TME_KO_Shift)
|
||||||
|
/**< TME Hardware */
|
||||||
|
#define TME_KO_TME_HW (UINT32_C(0x00) << TME_KO_Shift)
|
||||||
|
/**< TME Firmware */
|
||||||
|
#define TME_KO_TME_FW (UINT32_C(0x01) << TME_KO_Shift)
|
||||||
|
/**< TZ (= APPS-S) */
|
||||||
|
#define TME_KO_TZ (UINT32_C(0x02) << TME_KO_Shift)
|
||||||
|
/**< HLOS / HYP (= APPS-NS) */
|
||||||
|
#define TME_KO_HLOS_HYP (UINT32_C(0x03) << TME_KO_Shift)
|
||||||
|
/**< Modem */
|
||||||
|
#define TME_KO_MDM (UINT32_C(0x04) << TME_KO_Shift)
|
||||||
|
/**< SPU */
|
||||||
|
#define TME_KO_SPU (UINT32_C(0x0F) << TME_KO_Shift)
|
||||||
|
|
||||||
|
/** Key Lineage */
|
||||||
|
/**< Position of Key Lineage bits */
|
||||||
|
#define TME_KLI_Shift 30
|
||||||
|
/**< Mask for Key Lineage bits */
|
||||||
|
#define TME_KLI_Mask (UINT32_C(0x03) << TME_KLI_Shift)
|
||||||
|
/**< Not applicable */
|
||||||
|
#define TME_KLI_NA (UINT32_C(0x00) << TME_KLI_Shift)
|
||||||
|
/**< Not provisioned, chip unique */
|
||||||
|
#define TME_KLI_NP_CU (UINT32_C(0x01) << TME_KLI_Shift)
|
||||||
|
/**< Provisioned, not chip unique */
|
||||||
|
#define TME_KLI_P_NCU (UINT32_C(0x02) << TME_KLI_Shift)
|
||||||
|
/**< Provisioned, chip unique */
|
||||||
|
#define TME_KLI_P_CU (UINT32_C(0x03) << TME_KLI_Shift)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fields in Key Policy high word *
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** Reserved Bits, Group 1 */
|
||||||
|
/**< Position of Reserved bits */
|
||||||
|
#define TME_KR1_Shift (32 - TME_KPHALFBITS)
|
||||||
|
/**< Mask for Reserved bits */
|
||||||
|
#define TME_KR1_Mask (UINT32_C(0x01) << TME_KR1_Shift)
|
||||||
|
|
||||||
|
/** Key Wrapping Constraints */
|
||||||
|
/**< Position of Key Attribute bits */
|
||||||
|
#define TME_KWC_Shift (33 - TME_KPHALFBITS)
|
||||||
|
/**< Mask for Key Attribute bits */
|
||||||
|
#define TME_KWC_Mask (UINT32_C(0x0F) << TME_KWC_Shift)
|
||||||
|
/**< Key is wrappable with KWK_EXPORT */
|
||||||
|
#define TME_KWC_Wrappable_KXP (UINT32_C(0x01) << TME_KWC_Shift)
|
||||||
|
/**< Key is wrappable with KWK_STORAGE */
|
||||||
|
#define TME_KWC_Wrappable_KWK (UINT32_C(0x02) << TME_KWC_Shift)
|
||||||
|
/**< Key is wrappable with KWK_TRANSPORT */
|
||||||
|
#define TME_KWC_Wrappable_KTP (UINT32_C(0x04) << TME_KWC_Shift)
|
||||||
|
/**< Key is wrappable with KWK_SESSION */
|
||||||
|
#define TME_KWC_Wrappable_KSK (UINT32_C(0x08) << TME_KWC_Shift)
|
||||||
|
|
||||||
|
/** Throttling */
|
||||||
|
/**< Position of Throttling bits */
|
||||||
|
#define TME_KTH_Shift (37 - TME_KPHALFBITS)
|
||||||
|
/**< Mask for Throttling bits */
|
||||||
|
#define TME_KTH_Mask (UINT32_C(0x01) << TME_KTH_Shift)
|
||||||
|
/**< Throttling enabled */
|
||||||
|
#define TME_KTH_Enabled (UINT32_C(0x01) << TME_KTH_Shift)
|
||||||
|
|
||||||
|
/** Reserved Bits, Group 2 */
|
||||||
|
/**< Position of Reserved bits */
|
||||||
|
#define TME_KR2_Shift (38 - TME_KPHALFBITS)
|
||||||
|
/**< Mask for Reserved bits */
|
||||||
|
#define TME_KR2_Mask (UINT32_C(0x3F) << TME_KR2_Shift)
|
||||||
|
|
||||||
|
/** Key Policy Version */
|
||||||
|
/**< Position of Key Policy Version bits */
|
||||||
|
#define TME_KPV_Shift (44 - TME_KPHALFBITS)
|
||||||
|
/**< Mask for Key Policy Version bits */
|
||||||
|
#define TME_KPV_Mask (UINT32_C(0x0F) << TME_KPV_Shift)
|
||||||
|
/**< Mask for Key Policy Version bits */
|
||||||
|
#define TME_KPV_Version (UINT32_C(0x03) << TME_KPV_Shift)
|
||||||
|
|
||||||
|
/** Key Authorised Users */
|
||||||
|
/**< Position of Authorised User bits */
|
||||||
|
#define TME_KAU_Shift (48 - TME_KPHALFBITS)
|
||||||
|
/**< Mask for Authorised User bits */
|
||||||
|
#define TME_KAU_Mask (UINT32_C(0xFF) << TME_KAU_Shift)
|
||||||
|
/**< Key usable by TME Hardware */
|
||||||
|
#define TME_KAU_TME_HW (UINT32_C(0x01) << TME_KAU_Shift)
|
||||||
|
/**< Key usable by TME Firmware */
|
||||||
|
#define TME_KAU_TME_FW (UINT32_C(0x02) << TME_KAU_Shift)
|
||||||
|
/**< Key usable by TZ (= APPS_S) */
|
||||||
|
#define TME_KAU_TZ (UINT32_C(0x04) << TME_KAU_Shift)
|
||||||
|
/**< Key usable by HLOS / HYP (= APPS_NS) */
|
||||||
|
#define TME_KAU_HLOS_HYP (UINT32_C(0x08) << TME_KAU_Shift)
|
||||||
|
/**< Key usable by Modem */
|
||||||
|
#define TME_KAU_MDM (UINT32_C(0x10) << TME_KAU_Shift)
|
||||||
|
/**< Key usable by SPU */
|
||||||
|
#define TME_KAU_SPU (UINT32_C(0x20) << TME_KAU_Shift)
|
||||||
|
/**< Key usable by all EEs */
|
||||||
|
#define TME_KAU_ALL TME_KAU_Mask
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Credentials for throttling
|
||||||
|
*/
|
||||||
|
#define TME_CRED_SLOT_ID_NONE 0 /**< No throttling */
|
||||||
|
#define TME_CRED_SLOT_ID_1 1 /**< Credential slot 1 */
|
||||||
|
#define TME_CRED_SLOT_ID_2 2 /**< Credential slot 2 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* KDFSpec and associated structures
|
||||||
|
*/
|
||||||
|
/** Maximum context size that can be sent to the TME, in bytes */
|
||||||
|
#define TME_KDF_SW_CONTEXT_BYTES_MAX 128
|
||||||
|
#define TME_KDF_SALT_LABEL_BYTES_MAX 64
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Security info to be appended to a KDF context by the Sequencer
|
||||||
|
*
|
||||||
|
* These fields allow keys to be tied to specific devices, states,
|
||||||
|
* OEMs, subsystems, etc.
|
||||||
|
* Values are obtained by the Sequencer from hardware, such as
|
||||||
|
* fuses or internal registers.
|
||||||
|
*/
|
||||||
|
#define TME_KSC_SOCTestSignState 0x00000001 /**< (32 bits) */
|
||||||
|
#define TME_KSC_SOCSecBootState 0x00000002 /**< (8 bits) */
|
||||||
|
#define TME_KSC_SOCDebugState 0x00000004 /**< (8 bits) */
|
||||||
|
#define TME_KSC_TMELifecycleState 0x00000008 /**< (8 bits) */
|
||||||
|
#define TME_KSC_BootStageOTP 0x00000010 /**< (8 bits) */
|
||||||
|
#define TME_KSC_SWContext 0x00000020 /**< (variable) */
|
||||||
|
#define TME_KSC_ChildKeyPolicy 0x00000040 /**< (64 bits) */
|
||||||
|
#define TME_KSC_MixingKey 0x00000080 /**< (key len) */
|
||||||
|
#define TME_KSC_ChipUniqueID 0x00000100 /**< (64 bits) */
|
||||||
|
#define TME_KSC_ChipDeviceNumber 0x00000200 /**< (32 bits) */
|
||||||
|
#define TME_KSC_TMEPatchVer 0x00000400 /**< (512 bits) */
|
||||||
|
#define TME_KSC_SOCPatchVer 0x00000800 /**< (512 bits) */
|
||||||
|
#define TME_KSC_OEMID 0x00001000 /**< (16 bits) */
|
||||||
|
#define TME_KSC_OEMProductID 0x00002000 /**< (16 bits) */
|
||||||
|
#define TME_KSC_TMEImgSecVer 0x00004000 /**< (512 bits) */
|
||||||
|
#define TME_KSC_SOCInitImgSecVer 0x00008000 /**< (512 bits) */
|
||||||
|
#define TME_KSC_OEMMRCHash 0x00010000 /**< (512 bits) */
|
||||||
|
#define TME_KSC_OEMProductSeed 0x00020000 /**< (128 bits) */
|
||||||
|
#define TME_KSC_SeqPatchVer 0x00040000 /**< (512 bits) */
|
||||||
|
#define TME_KSC_HWMeasurement1 0x00080000 /**< (512 bits) */
|
||||||
|
#define TME_KSC_HWMeasurement2 0x00100000 /**< (512 bits) */
|
||||||
|
#define TME_KSC_Reserved 0xFFE00000 /**< RFU */
|
||||||
|
|
||||||
|
/** KDF Specification: encompasses both HKDF and NIST KDF algorithms */
|
||||||
|
struct tme_kdf_spec {
|
||||||
|
/* Info common to HKDF and NIST algorithms */
|
||||||
|
/**< @c TME_KAL_KDF_HKDF or @c TME_KAL_KDF_NIST */
|
||||||
|
uint32_t kdfalgo;
|
||||||
|
/**< IKM for HKDF; IKS for NIST */
|
||||||
|
uint32_t inputkey;
|
||||||
|
/**< If @c TME_KSC_MixingKey set in Security Context */
|
||||||
|
uint32_t mixkey;
|
||||||
|
/**< If deriving a L3 key */
|
||||||
|
uint32_t l2key;
|
||||||
|
/**< Derived key policy */
|
||||||
|
struct tme_key_policy policy;
|
||||||
|
/**< Software provided context */
|
||||||
|
uint8_t swcontext[TME_KDF_SW_CONTEXT_BYTES_MAX];
|
||||||
|
/**< Length of @c swContext in bytes */
|
||||||
|
uint32_t swcontextLength;
|
||||||
|
/**< Info to be appended to @c swContext */
|
||||||
|
uint32_t security_context;
|
||||||
|
/**< Salt for HKDF; Label for NIST */
|
||||||
|
uint8_t salt_label[TME_KDF_SALT_LABEL_BYTES_MAX];
|
||||||
|
/**< Length of @c saltLabel in bytes */
|
||||||
|
uint32_t salt_labelLength;
|
||||||
|
/* Additional info specific to HKDF: kdfAlgo == @c KAL_KDF_HKDF */
|
||||||
|
/**< PRF Digest algorithm: @c KAL_SHA256_HMAC or @c KAL_SHA512_HMAC */
|
||||||
|
uint32_t prf_digest_algo;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WrappedKey and associated structures
|
||||||
|
*/
|
||||||
|
/* Maximum wrapped key context size, in bytes */
|
||||||
|
/**< Cipher Text 68B, MAC 16B, KeyPolicy 8B, Nonce 8B */
|
||||||
|
#define TME_WK_CONTEXT_BYTES_MAX 100
|
||||||
|
struct tme_wrapped_key {
|
||||||
|
/**< Wrapped key context */
|
||||||
|
uint8_t key[TME_WK_CONTEXT_BYTES_MAX];
|
||||||
|
/**< Length of @c key in bytes*/
|
||||||
|
uint32_t length;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plain text Key and associated structures
|
||||||
|
*/
|
||||||
|
/* Maximum plain text key size, in bytes */
|
||||||
|
#define TME_PT_KEY_BYTES_MAX 68
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key format for intrinsically word aligned key
|
||||||
|
* lengths like 128/256/384/512... bits.
|
||||||
|
*
|
||||||
|
* Example: 256-bit key integer representation,
|
||||||
|
* Key = 0xK31 K30 K29.......K0
|
||||||
|
* Byte array, key[] = {0xK31, 0xK30, 0xK29, ...., 0xK0}
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Key format for non-word aligned key lengths like 521 bits.
|
||||||
|
* The key length is rounded off to next word ie, 544 bits.
|
||||||
|
*
|
||||||
|
* Example: 521-bit key, Key = 0xK65 K64 K63.......K2 K1 K0
|
||||||
|
* [bits 1-7 of K0 is expected to be zeros]
|
||||||
|
* 544 bit integer representation, Key = 0xK65 K64 K63.......K2 K1 K0 00 00
|
||||||
|
* Byte array, key[] = {0xK65, 0xK64, 0xK63, ...., 0xK2, 0xK1, 0xK0, 0x00, 0x00}
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct tme_plaintext_key {
|
||||||
|
/**< Plain text key */
|
||||||
|
uint8_t key[TME_PT_KEY_BYTES_MAX];
|
||||||
|
/**< Length of @c key in bytes */
|
||||||
|
uint32_t length;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extended Error Information structure
|
||||||
|
*/
|
||||||
|
struct tme_ext_err_info {
|
||||||
|
/* TME FW */
|
||||||
|
/**< TME FW Response status. */
|
||||||
|
uint32_t tme_err_status;
|
||||||
|
|
||||||
|
/* SEQ FW */
|
||||||
|
/**< Contents of CSR_CMD_ERROR_STATUS */
|
||||||
|
uint32_t seq_err_status;
|
||||||
|
|
||||||
|
/* SEQ HW Key Policy */
|
||||||
|
/**< CRYPTO_ENGINE_CRYPTO_KEY_POLICY_ERROR_STATUS0 */
|
||||||
|
uint32_t seq_kp_err_status0;
|
||||||
|
/**< CRYPTO_ENGINE_CRYPTO_KEY_POLICY_ERROR_STATUS1 */
|
||||||
|
uint32_t seq_kp_err_status1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Debug information: log/print this information
|
||||||
|
* if any of the above fields is non-zero
|
||||||
|
*/
|
||||||
|
/**< Contents of CSR_CMD_RESPONSE_STATUS */
|
||||||
|
uint32_t seq_rsp_status;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
#endif /* _TME_HWKM_MASTER_DEFS_H_ */
|
||||||
|
|
||||||
@@ -5,6 +5,7 @@ PRODUCT_PACKAGES += $(KERNEL_MODULES_OUT)/smcinvoke_dlkm.ko \
|
|||||||
$(KERNEL_MODULES_OUT)/qce50_dlkm.ko \
|
$(KERNEL_MODULES_OUT)/qce50_dlkm.ko \
|
||||||
$(KERNEL_MODULES_OUT)/qcrypto-msm_dlkm.ko \
|
$(KERNEL_MODULES_OUT)/qcrypto-msm_dlkm.ko \
|
||||||
$(KERNEL_MODULES_OUT)/hdcp_qseecom_dlkm.ko \
|
$(KERNEL_MODULES_OUT)/hdcp_qseecom_dlkm.ko \
|
||||||
|
$(KERNEL_MODULES_OUT)/tmecom-intf_dlkm.ko \
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,4 +4,5 @@ BOARD_VENDOR_KERNEL_MODULES += $(KERNEL_MODULES_OUT)/smcinvoke_dlkm.ko \
|
|||||||
$(KERNEL_MODULES_OUT)/qcrypto-msm_dlkm.ko \
|
$(KERNEL_MODULES_OUT)/qcrypto-msm_dlkm.ko \
|
||||||
$(KERNEL_MODULES_OUT)/qce50_dlkm.ko \
|
$(KERNEL_MODULES_OUT)/qce50_dlkm.ko \
|
||||||
$(KERNEL_MODULES_OUT)/hdcp_qseecom_dlkm.ko \
|
$(KERNEL_MODULES_OUT)/hdcp_qseecom_dlkm.ko \
|
||||||
|
$(KERNEL_MODULES_OUT)/tmecom-intf_dlkm.ko \
|
||||||
|
|
||||||
|
|||||||
404
tmecom/tme_hwkm_master.c
Normal file
404
tmecom/tme_hwkm_master.c
Normal file
@@ -0,0 +1,404 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
|
||||||
|
#include "tme_hwkm_master_intf.h"
|
||||||
|
#include "tmecom.h"
|
||||||
|
|
||||||
|
#define TME_MSG_CBOR_TAG_HWKM (303)
|
||||||
|
|
||||||
|
#define TME_CLEAR_KEY_CBOR_TAG 0x482F01D9 /* _be32 0xD9012F48 */
|
||||||
|
#define TME_DERIVE_KEY_CBOR_TAG 0x582F01D9 /* _be32 0xD9012F58 */
|
||||||
|
#define TME_GENERATE_KEY_CBOR_TAG 0x542F01D9 /* _be32 0xD9012F54 */
|
||||||
|
#define TME_IMPORT_KEY_CBOR_TAG 0x582F01D9 /* _be32 0xD9012F58 */
|
||||||
|
#define TME_WRAP_KEY_CBOR_TAG 0x502F01D9 /* _be32 0xD9012F50 */
|
||||||
|
#define TME_UNWRAP_KEY_CBOR_TAG 0x582F01D9 /* _be32 0xD9012F58 */
|
||||||
|
#define TME_BORADCAST_KEY_CBOR_TAG 0x442F01D9 /* _be32 0xD9012F44 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Static alloc for wrapped key
|
||||||
|
* Protected by tmecom dev mutex
|
||||||
|
*/
|
||||||
|
static struct wrap_key_resp gwrpk_response = {0};
|
||||||
|
|
||||||
|
static inline uint32_t update_ext_err(
|
||||||
|
struct tme_ext_err_info *err_info,
|
||||||
|
struct tme_response_sts *result)
|
||||||
|
{
|
||||||
|
bool is_failure = false;
|
||||||
|
|
||||||
|
err_info->tme_err_status = result->tme_err_status;
|
||||||
|
err_info->seq_err_status = result->seq_err_status;
|
||||||
|
err_info->seq_kp_err_status0 = result->seq_kp_err_status0;
|
||||||
|
err_info->seq_kp_err_status1 = result->seq_kp_err_status1;
|
||||||
|
err_info->seq_rsp_status = result->seq_rsp_status;
|
||||||
|
|
||||||
|
is_failure = err_info->tme_err_status ||
|
||||||
|
err_info->seq_err_status ||
|
||||||
|
err_info->seq_kp_err_status0 ||
|
||||||
|
err_info->seq_kp_err_status1;
|
||||||
|
|
||||||
|
print_hex_dump_bytes("err_info decoded bytes : ",
|
||||||
|
DUMP_PREFIX_ADDRESS, (void *)err_info,
|
||||||
|
sizeof(*err_info));
|
||||||
|
|
||||||
|
return is_failure ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t tme_hwkm_master_clearkey(uint32_t key_id,
|
||||||
|
struct tme_ext_err_info *err_info)
|
||||||
|
{
|
||||||
|
struct clear_key_req *request = NULL;
|
||||||
|
struct tme_response_sts *response = NULL;
|
||||||
|
uint32_t ret = 0;
|
||||||
|
size_t response_len = sizeof(*response);
|
||||||
|
|
||||||
|
if (!err_info)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
request = kzalloc(sizeof(*request), GFP_KERNEL);
|
||||||
|
response = kzalloc(response_len, GFP_KERNEL);
|
||||||
|
|
||||||
|
if (!request || !response) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
request->cmd.code = TME_HWKM_CMD_CLEAR_KEY;
|
||||||
|
request->key_id = key_id;
|
||||||
|
request->cbor_header = TME_CLEAR_KEY_CBOR_TAG;
|
||||||
|
|
||||||
|
ret = tmecom_process_request(request, sizeof(*request), response,
|
||||||
|
&response_len);
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
pr_err("HWKM clear key request failed for %d\n", key_id);
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response_len != sizeof(*response)) {
|
||||||
|
pr_err("HWKM response failed with invalid length: %u, %u\n",
|
||||||
|
response_len, sizeof(response));
|
||||||
|
ret = -EBADMSG;
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = update_ext_err(err_info, response);
|
||||||
|
|
||||||
|
err_exit:
|
||||||
|
kfree(request);
|
||||||
|
kfree(response);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(tme_hwkm_master_clearkey);
|
||||||
|
|
||||||
|
uint32_t tme_hwkm_master_generatekey(uint32_t key_id,
|
||||||
|
struct tme_key_policy *policy,
|
||||||
|
uint32_t cred_slot,
|
||||||
|
struct tme_ext_err_info *err_info)
|
||||||
|
{
|
||||||
|
struct gen_key_req *request = NULL;
|
||||||
|
struct tme_response_sts *response = NULL;
|
||||||
|
uint32_t ret = 0;
|
||||||
|
size_t response_len = sizeof(*response);
|
||||||
|
|
||||||
|
if (!err_info || !policy)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
request = kzalloc(sizeof(*request), GFP_KERNEL);
|
||||||
|
response = kzalloc(response_len, GFP_KERNEL);
|
||||||
|
|
||||||
|
if (!request || !response) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
request->cmd.code = TME_HWKM_CMD_GENERATE_KEY;
|
||||||
|
request->key_id = key_id;
|
||||||
|
request->cred_slot = cred_slot;
|
||||||
|
request->cbor_header = TME_GENERATE_KEY_CBOR_TAG;
|
||||||
|
memcpy(&request->key_policy, policy, sizeof(*policy));
|
||||||
|
|
||||||
|
ret = tmecom_process_request(request, sizeof(*request), response,
|
||||||
|
&response_len);
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
pr_err("HWKM generate key request failed for %d\n", key_id);
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response_len != sizeof(*response)) {
|
||||||
|
pr_err("HWKM response failed with invalid length: %u, %u\n",
|
||||||
|
response_len, sizeof(response));
|
||||||
|
ret = -EBADMSG;
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = update_ext_err(err_info, response);
|
||||||
|
|
||||||
|
err_exit:
|
||||||
|
kfree(request);
|
||||||
|
kfree(response);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(tme_hwkm_master_generatekey);
|
||||||
|
|
||||||
|
uint32_t tme_hwkm_master_derivekey(uint32_t key_id,
|
||||||
|
struct tme_kdf_spec *kdf_info,
|
||||||
|
uint32_t cred_slot,
|
||||||
|
struct tme_ext_err_info *err_info)
|
||||||
|
{
|
||||||
|
struct derive_key_req *request = NULL;
|
||||||
|
struct tme_response_sts *response = NULL;
|
||||||
|
uint32_t ret = 0;
|
||||||
|
size_t response_len = sizeof(*response);
|
||||||
|
|
||||||
|
if (!kdf_info || !err_info)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
request = kzalloc(sizeof(*request), GFP_KERNEL);
|
||||||
|
response = kzalloc(response_len, GFP_KERNEL);
|
||||||
|
|
||||||
|
if (!request || !response) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
request->cmd.code = TME_HWKM_CMD_DERIVE_KEY;
|
||||||
|
request->key_id = key_id;
|
||||||
|
request->cred_slot = cred_slot;
|
||||||
|
request->cbor_header = TME_DERIVE_KEY_CBOR_TAG;
|
||||||
|
memcpy(&request->kdf_info, kdf_info, sizeof(*kdf_info));
|
||||||
|
|
||||||
|
ret = tmecom_process_request(request, sizeof(*request), response,
|
||||||
|
&response_len);
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
pr_err("HWKM derive key request failed for %d\n", key_id);
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response_len != sizeof(*response)) {
|
||||||
|
pr_err("HWKM response failed with invalid length: %u, %u\n",
|
||||||
|
response_len, sizeof(response));
|
||||||
|
ret = -EBADMSG;
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = update_ext_err(err_info, response);
|
||||||
|
|
||||||
|
err_exit:
|
||||||
|
kfree(request);
|
||||||
|
kfree(response);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(tme_hwkm_master_derivekey);
|
||||||
|
|
||||||
|
uint32_t tme_hwkm_master_wrapkey(uint32_t key_id,
|
||||||
|
uint32_t targetkey_id,
|
||||||
|
uint32_t cred_slot,
|
||||||
|
struct tme_wrapped_key *wrapped,
|
||||||
|
struct tme_ext_err_info *err_info)
|
||||||
|
{
|
||||||
|
struct wrap_key_req *request = NULL;
|
||||||
|
struct wrap_key_resp *wrpk_response = NULL;
|
||||||
|
uint32_t ret = 0;
|
||||||
|
size_t response_len = sizeof(*wrpk_response);
|
||||||
|
|
||||||
|
if (!wrapped || !err_info)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
request = kzalloc(sizeof(*request), GFP_KERNEL);
|
||||||
|
wrpk_response = &gwrpk_response;
|
||||||
|
|
||||||
|
if (!request)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
request->cmd.code = TME_HWKM_CMD_WRAP_KEY;
|
||||||
|
request->key_id = key_id;
|
||||||
|
request->target_key_id = targetkey_id;
|
||||||
|
request->cbor_header = TME_WRAP_KEY_CBOR_TAG;
|
||||||
|
|
||||||
|
ret = tmecom_process_request(request, sizeof(*request), wrpk_response,
|
||||||
|
&response_len);
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
pr_err("HWKM wrap key request failed for %d\n", key_id);
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response_len != sizeof(*wrpk_response)) {
|
||||||
|
pr_err("HWKM response failed with invalid length: %u, %u\n",
|
||||||
|
response_len, sizeof(wrpk_response));
|
||||||
|
ret = -EBADMSG;
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = update_ext_err(err_info, &wrpk_response->status);
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
memcpy(wrapped, &wrpk_response->wrapped_key, sizeof(*wrapped));
|
||||||
|
|
||||||
|
err_exit:
|
||||||
|
kfree(request);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(tme_hwkm_master_wrapkey);
|
||||||
|
|
||||||
|
uint32_t tme_hwkm_master_unwrapkey(uint32_t key_id,
|
||||||
|
uint32_t kwkey_id,
|
||||||
|
uint32_t cred_slot,
|
||||||
|
struct tme_wrapped_key *wrapped,
|
||||||
|
struct tme_ext_err_info *err_info)
|
||||||
|
{
|
||||||
|
struct unwrap_key_req *request = NULL;
|
||||||
|
struct tme_response_sts *response = NULL;
|
||||||
|
uint32_t ret = 0;
|
||||||
|
size_t response_len = sizeof(*response);
|
||||||
|
|
||||||
|
if (!wrapped || !err_info)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
request = kzalloc(sizeof(*request), GFP_KERNEL);
|
||||||
|
response = kzalloc(response_len, GFP_KERNEL);
|
||||||
|
|
||||||
|
if (!request || !response) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
request->cmd.code = TME_HWKM_CMD_UNWRAP_KEY;
|
||||||
|
request->key_id = key_id;
|
||||||
|
request->kw_key_id = kwkey_id;
|
||||||
|
request->cbor_header = TME_UNWRAP_KEY_CBOR_TAG;
|
||||||
|
memcpy(&request->wrapped, wrapped, sizeof(*wrapped));
|
||||||
|
|
||||||
|
ret = tmecom_process_request(request, sizeof(*request), response,
|
||||||
|
&response_len);
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
pr_err("HWKM unwrap key request failed for %d\n", key_id);
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response_len != sizeof(*response)) {
|
||||||
|
pr_err("HWKM response failed with invalid length: %u, %u\n",
|
||||||
|
response_len, sizeof(response));
|
||||||
|
ret = -EBADMSG;
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = update_ext_err(err_info, response);
|
||||||
|
|
||||||
|
err_exit:
|
||||||
|
kfree(request);
|
||||||
|
kfree(response);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(tme_hwkm_master_unwrapkey);
|
||||||
|
|
||||||
|
uint32_t tme_hwkm_master_importkey(uint32_t key_id,
|
||||||
|
struct tme_key_policy *policy,
|
||||||
|
struct tme_plaintext_key *key_material,
|
||||||
|
uint32_t cred_slot,
|
||||||
|
struct tme_ext_err_info *err_info)
|
||||||
|
{
|
||||||
|
struct import_key_req *request = NULL;
|
||||||
|
struct tme_response_sts *response = NULL;
|
||||||
|
uint32_t ret = 0;
|
||||||
|
size_t response_len = sizeof(*response);
|
||||||
|
|
||||||
|
if (!key_material || !err_info || !policy)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
request = kzalloc(sizeof(*request), GFP_KERNEL);
|
||||||
|
response = kzalloc(response_len, GFP_KERNEL);
|
||||||
|
|
||||||
|
if (!request || !response) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
request->cmd.code = TME_HWKM_CMD_IMPORT_KEY;
|
||||||
|
request->key_id = key_id;
|
||||||
|
request->cred_slot = cred_slot;
|
||||||
|
request->cbor_header = TME_IMPORT_KEY_CBOR_TAG;
|
||||||
|
memcpy(&request->key_policy, policy, sizeof(*policy));
|
||||||
|
memcpy(&request->key_material, key_material, sizeof(*key_material));
|
||||||
|
|
||||||
|
ret = tmecom_process_request(request, sizeof(*request), response,
|
||||||
|
&response_len);
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
pr_err("HWKM import key request failed for %d\n", key_id);
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response_len != sizeof(*response)) {
|
||||||
|
pr_err("HWKM response failed with invalid length: %u, %u\n",
|
||||||
|
response_len, sizeof(response));
|
||||||
|
ret = -EBADMSG;
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = update_ext_err(err_info, response);
|
||||||
|
|
||||||
|
err_exit:
|
||||||
|
kfree(request);
|
||||||
|
kfree(response);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(tme_hwkm_master_importkey);
|
||||||
|
|
||||||
|
uint32_t tme_hwkm_master_broadcast_transportkey(
|
||||||
|
struct tme_ext_err_info *err_info)
|
||||||
|
{
|
||||||
|
struct broadcast_tpkey_req *request = NULL;
|
||||||
|
struct tme_response_sts *response = NULL;
|
||||||
|
uint32_t ret = 0;
|
||||||
|
size_t response_len = sizeof(*response);
|
||||||
|
|
||||||
|
if (!err_info)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
request = kzalloc(sizeof(*request), GFP_KERNEL);
|
||||||
|
response = kzalloc(response_len, GFP_KERNEL);
|
||||||
|
|
||||||
|
if (!request || !response) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
request->cbor_header = TME_BORADCAST_KEY_CBOR_TAG;
|
||||||
|
request->cmd.code = TME_HWKM_CMD_BROADCAST_TP_KEY;
|
||||||
|
|
||||||
|
ret = tmecom_process_request(request, sizeof(*request), response,
|
||||||
|
&response_len);
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
pr_err("HWKM broadcast TP key request failed\n");
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response_len != sizeof(*response)) {
|
||||||
|
pr_err("HWKM response failed with invalid length: %u, %u\n",
|
||||||
|
response_len, sizeof(response));
|
||||||
|
ret = -EBADMSG;
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = update_ext_err(err_info, response);
|
||||||
|
|
||||||
|
err_exit:
|
||||||
|
kfree(request);
|
||||||
|
kfree(response);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(tme_hwkm_master_broadcast_transportkey);
|
||||||
|
|
||||||
132
tmecom/tme_hwkm_master_intf.h
Normal file
132
tmecom/tme_hwkm_master_intf.h
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||||
|
*/
|
||||||
|
#ifndef _TME_HWKM_MASTER_INTERFACE_H_
|
||||||
|
#define _TME_HWKM_MASTER_INTERFACE_H_
|
||||||
|
|
||||||
|
#include <linux/tme_hwkm_master_defs.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HWKM Master command IDs
|
||||||
|
*/
|
||||||
|
enum tme_hwkm_cmd {
|
||||||
|
TME_HWKM_CMD_CLEAR_KEY = 0, /**< Clear Key */
|
||||||
|
TME_HWKM_CMD_GENERATE_KEY = 1, /**< Generate Key */
|
||||||
|
TME_HWKM_CMD_DERIVE_KEY = 2, /**< Derive Key, NIST or HKDF */
|
||||||
|
TME_HWKM_CMD_WRAP_KEY = 3, /**< Wrap Key */
|
||||||
|
TME_HWKM_CMD_UNWRAP_KEY = 4, /**< Unwrap Key */
|
||||||
|
TME_HWKM_CMD_IMPORT_KEY = 5, /**< Import Key */
|
||||||
|
TME_HWKM_CMD_BROADCAST_TP_KEY = 6, /**< Broadcast Transport Key */
|
||||||
|
TMW_HWKM_CMD_INVALID = 7, /**< Invalid cmd */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opcode and response structures
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Values as per TME_HWKM_CMD_* */
|
||||||
|
struct tme_hwkm_master_cmd {
|
||||||
|
uint32_t code;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
|
||||||
|
struct tme_response_sts {
|
||||||
|
/* TME FW */
|
||||||
|
uint32_t tme_err_status; /**< TME FW Response status. */
|
||||||
|
|
||||||
|
/* SEQ FW */
|
||||||
|
uint32_t seq_err_status; /**< Contents of CSR_CMD_ERROR_STATUS */
|
||||||
|
|
||||||
|
/* SEQ HW Key Policy */
|
||||||
|
uint32_t seq_kp_err_status0; /**< CRYPTO_ENGINE_CRYPTO_KEY_POLICY_ERROR_STATUS0 */
|
||||||
|
uint32_t seq_kp_err_status1; /**< CRYPTO_ENGINE_CRYPTO_KEY_POLICY_ERROR_STATUS1 */
|
||||||
|
|
||||||
|
/* Debug information: log/print this information if any of the above fields is non-zero */
|
||||||
|
uint32_t seq_rsp_status; /**< Contents of CSR_CMD_RESPONSE_STATUS */
|
||||||
|
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear Key ID structures
|
||||||
|
*/
|
||||||
|
struct clear_key_req {
|
||||||
|
uint32_t cbor_header; /**< CBOR encoded tag */
|
||||||
|
struct tme_hwkm_master_cmd cmd; /**< @c TME_HWKM_CMD_CLEAR_KEY */
|
||||||
|
uint32_t key_id; /**< The ID of the key to clear.*/
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate Key ID structures
|
||||||
|
*/
|
||||||
|
struct gen_key_req {
|
||||||
|
uint32_t cbor_header; /**< CBOR encoded tag */
|
||||||
|
struct tme_hwkm_master_cmd cmd; /**< @c TME_HWKM_CMD_GENERATE_KEY */
|
||||||
|
uint32_t key_id; /**< The ID of the key to be generated. */
|
||||||
|
struct tme_key_policy key_policy;/**< The policy specifying the key to be generated. */
|
||||||
|
uint32_t cred_slot; /**< Credential slot to which this key will be bound. */
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Derive Key ID structures
|
||||||
|
*/
|
||||||
|
struct derive_key_req {
|
||||||
|
uint32_t cbor_header; /**< CBOR encoded tag */
|
||||||
|
struct tme_hwkm_master_cmd cmd; /**< @c TME_HWKM_CMD_DERIVE_KEY */
|
||||||
|
uint32_t key_id; /**< The ID of the key to be derived. */
|
||||||
|
struct tme_kdf_spec kdf_info; /**< Specifies how the key is to be derived. */
|
||||||
|
uint32_t cred_slot; /**< Credential slot to which this key will be bound. */
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrap Key ID structures
|
||||||
|
*/
|
||||||
|
struct wrap_key_req {
|
||||||
|
uint32_t cbor_header; /**< CBOR encoded tag */
|
||||||
|
struct tme_hwkm_master_cmd cmd;/**< @c TME_HWKM_CMD_WRAP_KEY */
|
||||||
|
uint32_t key_id; /**< The ID of the key to secure the target key. */
|
||||||
|
uint32_t target_key_id; /**< Denotes the key to be wrapped. */
|
||||||
|
uint32_t cred_slot; /**< Credential slot to which this key is bound. */
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
|
||||||
|
struct wrap_key_resp {
|
||||||
|
struct tme_response_sts status; /**< Response status. */
|
||||||
|
struct tme_wrapped_key wrapped_key; /**< The wrapped key. */
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unwrap Key ID structures
|
||||||
|
*/
|
||||||
|
struct unwrap_key_req {
|
||||||
|
uint32_t cbor_header; /**< CBOR encoded tag */
|
||||||
|
struct tme_hwkm_master_cmd cmd;/**< @c TME_HWKM_CMD_UNWRAP_KEY */
|
||||||
|
uint32_t key_id; /**< The ID of the key to be unwrapped. */
|
||||||
|
uint32_t kw_key_id; /**< The ID of the key to be used to unwrap the key. */
|
||||||
|
struct tme_wrapped_key wrapped; /**< The key to be unwrapped. */
|
||||||
|
uint32_t cred_slot; /**< Credential slot to which this key will be bound. */
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import Key ID structures
|
||||||
|
*/
|
||||||
|
struct import_key_req {
|
||||||
|
uint32_t cbor_header; /**< CBOR encoded tag */
|
||||||
|
struct tme_hwkm_master_cmd cmd; /**< @c TME_HWKM_CMD_IMPORT_KEY */
|
||||||
|
uint32_t key_id; /**< The ID of the key to be imported. */
|
||||||
|
struct tme_key_policy key_policy;/**< The Key Policy to be associated with the key. */
|
||||||
|
struct tme_plaintext_key key_material;/**< The plain-text key material. */
|
||||||
|
uint32_t cred_slot; /**< Credential slot to which this key will be bound. */
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Broadcast Transport Key structures
|
||||||
|
*/
|
||||||
|
struct broadcast_tpkey_req {
|
||||||
|
uint32_t cbor_header; /**< CBOR encoded tag */
|
||||||
|
struct tme_hwkm_master_cmd cmd;/**< @c TME_HWKM_CMD_BROADCAST_TP_KEY */
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _TME_HWKM_MASTER_INTERFACE_H_ */
|
||||||
|
|
||||||
318
tmecom/tmecom.c
Normal file
318
tmecom/tmecom.c
Normal file
@@ -0,0 +1,318 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/mailbox_client.h>
|
||||||
|
#include <linux/seq_file.h>
|
||||||
|
#include <linux/debugfs.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/mailbox/qmp.h>
|
||||||
|
#include <linux/uaccess.h>
|
||||||
|
#include <linux/mailbox_controller.h>
|
||||||
|
|
||||||
|
#include "tmecom.h"
|
||||||
|
|
||||||
|
struct tmecom {
|
||||||
|
struct device *dev;
|
||||||
|
struct mbox_client cl;
|
||||||
|
struct mbox_chan *chan;
|
||||||
|
struct mutex lock;
|
||||||
|
struct qmp_pkt pkt;
|
||||||
|
wait_queue_head_t waitq;
|
||||||
|
void *txbuf;
|
||||||
|
bool rx_done;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_DEBUG_FS)
|
||||||
|
#include <linux/tme_hwkm_master_defs.h>
|
||||||
|
#include <linux/tme_hwkm_master.h>
|
||||||
|
|
||||||
|
char dpkt[MBOX_MAX_MSG_LEN + 1];
|
||||||
|
struct dentry *debugfs_file;
|
||||||
|
#endif /* CONFIG_DEBUG_FS */
|
||||||
|
|
||||||
|
static struct tmecom *tmedev;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tmecom_msg_hdr - Request/Response message header between HLOS and TME.
|
||||||
|
*
|
||||||
|
* This header is proceeding any request specific parameters.
|
||||||
|
* The transaction id is used to match request with response.
|
||||||
|
*
|
||||||
|
* Note: glink/QMP layer provides the rx/tx data size, so user payload size
|
||||||
|
* is calculated by reducing the header size.
|
||||||
|
*/
|
||||||
|
struct tmecom_msg_hdr {
|
||||||
|
unsigned int reserved; /* for future use */
|
||||||
|
unsigned int txnid; /* transaction id */
|
||||||
|
} __packed;
|
||||||
|
#define TMECOM_TX_HDR_SIZE sizeof(struct tmecom_msg_hdr)
|
||||||
|
#define CBOR_NUM_BYTES (sizeof(unsigned int))
|
||||||
|
#define TMECOM_RX_HDR_SIZE (TMECOM_TX_HDR_SIZE + CBOR_NUM_BYTES)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CBOR encode emulation
|
||||||
|
* Prepend tmecom_msg_hdr space
|
||||||
|
* CBOR tag is prepended in request
|
||||||
|
*/
|
||||||
|
static inline size_t tmecom_encode(struct tmecom *tdev, const void *reqbuf,
|
||||||
|
size_t size)
|
||||||
|
{
|
||||||
|
unsigned int *msg = tdev->txbuf + TMECOM_TX_HDR_SIZE;
|
||||||
|
unsigned int *src = (unsigned int *)reqbuf;
|
||||||
|
|
||||||
|
memcpy(msg, src, size);
|
||||||
|
return (size + TMECOM_TX_HDR_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CBOR decode emulation
|
||||||
|
* Strip tmecom_msg_hdr & CBOR tag
|
||||||
|
*/
|
||||||
|
static inline size_t tmecom_decode(struct tmecom *tdev, void *respbuf)
|
||||||
|
{
|
||||||
|
unsigned int *msg = tdev->pkt.data + TMECOM_RX_HDR_SIZE;
|
||||||
|
unsigned int *rbuf = (unsigned int *)respbuf;
|
||||||
|
|
||||||
|
memcpy(rbuf, msg, (tdev->pkt.size - TMECOM_RX_HDR_SIZE));
|
||||||
|
return (tdev->pkt.size - TMECOM_RX_HDR_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool tmecom_check_rx_done(struct tmecom *tdev)
|
||||||
|
{
|
||||||
|
return tdev->rx_done;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tmecom_process_request(const void *reqbuf, size_t reqsize, void *respbuf,
|
||||||
|
size_t *respsize)
|
||||||
|
{
|
||||||
|
struct tmecom *tdev = tmedev;
|
||||||
|
long time_left = 0;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check to handle if probe is not successful or not completed yet
|
||||||
|
*/
|
||||||
|
if (!tdev) {
|
||||||
|
pr_err("%s: tmecom dev is NULL\n", __func__);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!reqbuf || !reqsize || (reqsize > MBOX_MAX_MSG_LEN)) {
|
||||||
|
dev_err(tdev->dev, "invalid reqbuf or reqsize\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!respbuf || !respsize || (*respsize > MBOX_MAX_MSG_LEN)) {
|
||||||
|
dev_err(tdev->dev, "invalid respbuf or respsize\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_lock(&tdev->lock);
|
||||||
|
|
||||||
|
tdev->rx_done = false;
|
||||||
|
tdev->pkt.size = tmecom_encode(tdev, reqbuf, reqsize);
|
||||||
|
/*
|
||||||
|
* Controller expects a 4 byte aligned buffer
|
||||||
|
*/
|
||||||
|
tdev->pkt.size = (tdev->pkt.size + 0x3) & ~0x3;
|
||||||
|
tdev->pkt.data = tdev->txbuf;
|
||||||
|
|
||||||
|
pr_debug("tmecom encoded request size = %u\n", tdev->pkt.size);
|
||||||
|
print_hex_dump_bytes("tmecom sending bytes : ",
|
||||||
|
DUMP_PREFIX_ADDRESS, tdev->pkt.data, tdev->pkt.size);
|
||||||
|
|
||||||
|
if (mbox_send_message(tdev->chan, &tdev->pkt) < 0) {
|
||||||
|
dev_err(tdev->dev, "failed to send qmp message\n");
|
||||||
|
ret = -EAGAIN;
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
time_left = wait_event_interruptible_timeout(tdev->waitq,
|
||||||
|
tmecom_check_rx_done(tdev), tdev->cl.tx_tout);
|
||||||
|
|
||||||
|
if (!time_left) {
|
||||||
|
dev_err(tdev->dev, "request timed out\n");
|
||||||
|
ret = -ETIMEDOUT;
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_info(tdev->dev, "response received\n");
|
||||||
|
|
||||||
|
pr_debug("tmecom received size = %u\n", tdev->pkt.size);
|
||||||
|
print_hex_dump_bytes("tmecom received bytes : ",
|
||||||
|
DUMP_PREFIX_ADDRESS, tdev->pkt.data, tdev->pkt.size);
|
||||||
|
|
||||||
|
*respsize = tmecom_decode(tdev, respbuf);
|
||||||
|
|
||||||
|
tdev->rx_done = false;
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
err_exit:
|
||||||
|
mutex_unlock(&tdev->lock);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(tmecom_process_request);
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_DEBUG_FS)
|
||||||
|
static ssize_t tmecom_debugfs_write(struct file *file,
|
||||||
|
const char __user *userstr, size_t len, loff_t *pos)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
size_t rxlen = 0;
|
||||||
|
struct tme_ext_err_info *err_info = (struct tme_ext_err_info *)dpkt;
|
||||||
|
|
||||||
|
|
||||||
|
if (!len || (len > MBOX_MAX_MSG_LEN)) {
|
||||||
|
pr_err("invalid message length\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(dpkt, 0, sizeof(*dpkt));
|
||||||
|
ret = copy_from_user(dpkt, userstr, len);
|
||||||
|
if (ret) {
|
||||||
|
pr_err("%s copy from user failed, ret=%d\n", __func__, ret);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmecom_process_request(dpkt, len, dpkt, &rxlen);
|
||||||
|
|
||||||
|
print_hex_dump_bytes("tmecom decoded bytes : ",
|
||||||
|
DUMP_PREFIX_ADDRESS, dpkt, rxlen);
|
||||||
|
|
||||||
|
pr_debug("calling TME_HWKM_CMD_BROADCAST_TP_KEY api\n");
|
||||||
|
ret = tme_hwkm_master_broadcast_transportkey(err_info);
|
||||||
|
|
||||||
|
if (ret == 0)
|
||||||
|
pr_debug("%s successful\n", __func__);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct file_operations tmecom_debugfs_ops = {
|
||||||
|
.open = simple_open,
|
||||||
|
.write = tmecom_debugfs_write,
|
||||||
|
};
|
||||||
|
#endif /* CONFIG_DEBUG_FS */
|
||||||
|
|
||||||
|
static void tmecom_receive_message(struct mbox_client *client, void *message)
|
||||||
|
{
|
||||||
|
struct tmecom *tdev = dev_get_drvdata(client->dev);
|
||||||
|
struct qmp_pkt *pkt = NULL;
|
||||||
|
|
||||||
|
pr_debug("%s entered\n", __func__);
|
||||||
|
|
||||||
|
if (!message) {
|
||||||
|
dev_err(tdev->dev, "spurious message received\n");
|
||||||
|
goto tmecom_receive_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tdev->rx_done) {
|
||||||
|
dev_err(tdev->dev, "tmecom response pending\n");
|
||||||
|
goto tmecom_receive_end;
|
||||||
|
}
|
||||||
|
pkt = (struct qmp_pkt *)message;
|
||||||
|
tdev->pkt.size = pkt->size;
|
||||||
|
tdev->pkt.data = pkt->data;
|
||||||
|
tdev->rx_done = true;
|
||||||
|
tmecom_receive_end:
|
||||||
|
wake_up_interruptible(&tdev->waitq);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tmecom_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct tmecom *tdev;
|
||||||
|
const char *label;
|
||||||
|
char name[32];
|
||||||
|
|
||||||
|
tdev = devm_kzalloc(&pdev->dev, sizeof(*tdev), GFP_KERNEL);
|
||||||
|
if (!tdev)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
tdev->cl.dev = &pdev->dev;
|
||||||
|
tdev->cl.tx_block = true;
|
||||||
|
tdev->cl.tx_tout = 500;
|
||||||
|
tdev->cl.knows_txdone = false;
|
||||||
|
tdev->cl.rx_callback = tmecom_receive_message;
|
||||||
|
|
||||||
|
label = of_get_property(pdev->dev.of_node, "mbox-names", NULL);
|
||||||
|
if (!label)
|
||||||
|
return -EINVAL;
|
||||||
|
snprintf(name, 32, "%s_send_message", label);
|
||||||
|
|
||||||
|
tdev->chan = mbox_request_channel(&tdev->cl, 0);
|
||||||
|
if (IS_ERR(tdev->chan)) {
|
||||||
|
dev_err(&pdev->dev, "failed to get mbox channel\n");
|
||||||
|
return PTR_ERR(tdev->chan);
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_init(&tdev->lock);
|
||||||
|
|
||||||
|
if (tdev->chan) {
|
||||||
|
tdev->txbuf =
|
||||||
|
devm_kzalloc(&pdev->dev, MBOX_MAX_MSG_LEN, GFP_KERNEL);
|
||||||
|
if (!tdev->txbuf) {
|
||||||
|
dev_err(&pdev->dev, "message buffer alloc faile\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init_waitqueue_head(&tdev->waitq);
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_DEBUG_FS)
|
||||||
|
debugfs_file = debugfs_create_file(name, 0220, NULL, tdev,
|
||||||
|
&tmecom_debugfs_ops);
|
||||||
|
if (!debugfs_file)
|
||||||
|
goto err;
|
||||||
|
#endif /* CONFIG_DEBUG_FS */
|
||||||
|
|
||||||
|
tdev->rx_done = false;
|
||||||
|
tdev->dev = &pdev->dev;
|
||||||
|
dev_set_drvdata(&pdev->dev, tdev);
|
||||||
|
|
||||||
|
tmedev = tdev;
|
||||||
|
|
||||||
|
dev_info(&pdev->dev, "tmecom probe success\n");
|
||||||
|
return 0;
|
||||||
|
err:
|
||||||
|
mbox_free_channel(tdev->chan);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tmecom_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct tmecom *tdev = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_DEBUG_FS)
|
||||||
|
debugfs_remove(debugfs_file);
|
||||||
|
#endif /* CONFIG_DEBUG_FS */
|
||||||
|
|
||||||
|
if (tdev->chan)
|
||||||
|
mbox_free_channel(tdev->chan);
|
||||||
|
|
||||||
|
dev_info(&pdev->dev, "tmecom remove success\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct of_device_id tmecom_match_tbl[] = {
|
||||||
|
{.compatible = "qcom,tmecom-qmp-client"},
|
||||||
|
{},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_driver tmecom_driver = {
|
||||||
|
.probe = tmecom_probe,
|
||||||
|
.remove = tmecom_remove,
|
||||||
|
.driver = {
|
||||||
|
.name = "tmecom-qmp-client",
|
||||||
|
.suppress_bind_attrs = true,
|
||||||
|
.of_match_table = tmecom_match_tbl,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
module_platform_driver(tmecom_driver);
|
||||||
|
|
||||||
|
MODULE_DESCRIPTION("MSM TMECom QTI mailbox protocol client");
|
||||||
|
MODULE_LICENSE("GPL v2");
|
||||||
12
tmecom/tmecom.h
Normal file
12
tmecom/tmecom.h
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||||
|
*/
|
||||||
|
#ifndef _TMECOM_H_
|
||||||
|
#define _TMECOM_H_
|
||||||
|
|
||||||
|
#define MBOX_MAX_MSG_LEN 1024
|
||||||
|
|
||||||
|
int tmecom_process_request(const void *reqbuf, size_t reqsize, void *respbuf,
|
||||||
|
size_t *respsize);
|
||||||
|
#endif /*_TMECOM_H_ */
|
||||||
Reference in New Issue
Block a user