123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513 |
- /* SPDX-License-Identifier: GPL-2.0-only */
- /*
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
- */
- #ifndef __HWKM_H_
- #define __HWKM_H_
- #include <linux/types.h>
- #include <linux/tme_hwkm_master_defs.h>
- #include <linux/crypto-qti-common.h>
- #if IS_ENABLED(CONFIG_QTI_HW_KEY_MANAGER)
- /* Maximum number of bytes in a key used in a KEY_SLOT_RDWR operation */
- #define HWKM_MAX_KEY_SIZE TME_PT_KEY_BYTES_MAX
- /* Maximum number of bytes in a SW ctx used in a SYSTEM_KDF operation */
- #define HWKM_MAX_CTX_SIZE TME_KDF_SW_CONTEXT_BYTES_MAX
- /* Maximum number of bytes in a WKB used in a key wrap or unwrap operation */
- #define HWKM_MAX_BLOB_SIZE TME_WK_CONTEXT_BYTES_MAX
- #define HWKM_TPKEY_SLOT_MASTER TME_KID_TP
- #define HWKM_TPKEY_SLOT_ICE 0x8C
- #define HWKM_EXPECTED_UNWRAP_KEY_SIZE 100
- #endif /* CONFIG_QTI_HW_KEY_MANAGER */
- #if IS_ENABLED(CONFIG_QTI_HW_KEY_MANAGER_V1)
- /* Maximum number of bytes in a key used in a KEY_SLOT_RDWR operation */
- #define HWKM_MAX_KEY_SIZE 32
- /* Maximum number of bytes in a SW ctx used in a SYSTEM_KDF operation */
- #define HWKM_MAX_CTX_SIZE 64
- /* Maximum number of bytes in a WKB used in a key wrap or unwrap operation */
- #define HWKM_MAX_BLOB_SIZE 68
- #endif /* CONFIG_QTI_HW_KEY_MANAGER_V1 */
- /* Opcodes to be set in the op field of a command */
- enum hwkm_op {
- /* Opcode to generate a random key */
- NIST_KEYGEN = 0,
- /* Opcode to derive a key */
- SYSTEM_KDF,
- /* Used only by HW */
- QFPROM_KEY_RDWR,
- /* Opcode to wrap a key and export the wrapped key */
- KEY_WRAP_EXPORT,
- /*
- * Opcode to import a wrapped key and unwrap it in the
- * specified key slot
- */
- KEY_UNWRAP_IMPORT,
- /* Opcode to clear a slot */
- KEY_SLOT_CLEAR,
- /* Opcode to read or write a key from/to a slot */
- KEY_SLOT_RDWR,
- /*
- * Opcode to broadcast a TPKEY to all slaves configured
- * to receive a TPKEY.
- */
- SET_TPKEY,
- HWKM_MAX_OP,
- HWKM_UNDEF_OP = 0xFF
- };
- /*
- * Algorithm values which can be used in the alg_allowed field of the
- * key policy.
- */
- #if IS_ENABLED(CONFIG_QTI_HW_KEY_MANAGER)
- enum hwkm_alg {
- /* Symmetric Algorithms */
- AES128_ECB = TME_KT_Symmetric | TME_KAL_AES128_ECB | TME_KL_128,
- AES256_ECB = TME_KT_Symmetric | TME_KAL_AES256_ECB | TME_KL_256,
- DES_ECB = TME_KT_Symmetric | TME_KAL_DES_ECB | TME_KL_64,
- TDES_ECB = TME_KT_Symmetric | TME_KAL_TDES_ECB | TME_KL_192,
- AES128_CBC = TME_KT_Symmetric | TME_KAL_AES128_CBC | TME_KL_128,
- AES256_CBC = TME_KT_Symmetric | TME_KAL_AES256_CBC | TME_KL_256,
- DES_CBC = TME_KT_Symmetric | TME_KAL_DES_CBC | TME_KL_64,
- TDES_CBC = TME_KT_Symmetric | TME_KAL_TDES_CBC | TME_KL_192,
- AES128_CCM_TC = TME_KT_Symmetric | TME_KAL_AES128_CCM_TC | TME_KL_128,
- AES128_CCM_NTC = TME_KT_Symmetric | TME_KAL_AES128_CCM_NTC | TME_KL_128,
- AES256_CCM_TC = TME_KT_Symmetric | TME_KAL_AES256_CCM_TC | TME_KL_256,
- AES256_CCM_NTC = TME_KT_Symmetric | TME_KAL_AES256_CCM_NTC | TME_KL_256,
- AES256_SIV = TME_KT_Symmetric | TME_KAL_AES256_SIV | TME_KL_512,
- AES128_CTR = TME_KT_Symmetric | TME_KAL_AES128_CTR | TME_KL_128,
- AES256_CTR = TME_KT_Symmetric | TME_KAL_AES256_CTR | TME_KL_256,
- AES128_XTS = TME_KT_Symmetric | TME_KAL_AES128_XTS | TME_KL_512,
- AES256_XTS = TME_KT_Symmetric | TME_KAL_AES256_XTS | TME_KL_512,
- SHA1_HMAC = TME_KT_Symmetric | TME_KAL_SHA1_HMAC | TME_KL_512,
- SHA256_HMAC = TME_KT_Symmetric | TME_KAL_SHA256_HMAC | TME_KL_512,
- AES128_CMAC = TME_KT_Symmetric | TME_KAL_AES128_CMAC | TME_KL_128,
- AES256_CMAC = TME_KT_Symmetric | TME_KAL_AES256_CMAC | TME_KL_256,
- SHA384_HMAC = TME_KT_Symmetric | TME_KAL_SHA384_HMAC | TME_KL_512,
- SHA512_HMAC = TME_KT_Symmetric | TME_KAL_SHA512_HMAC | TME_KL_512,
- AES128_GCM = TME_KT_Symmetric | TME_KAL_AES128_GCM | TME_KL_128,
- AES256_GCM = TME_KT_Symmetric | TME_KAL_AES256_GCM | TME_KL_256,
- // TODO: Verify Key Lengths for these algorithms
- KASUMI = TME_KT_Symmetric | TME_KAL_KASUMI | TME_KL_128,
- SNOW3G = TME_KT_Symmetric | TME_KAL_SNOW3G | TME_KL_128,
- ZUC = TME_KT_Symmetric | TME_KAL_ZUC | TME_KL_128,
- PRINCE = TME_KT_Symmetric | TME_KAL_PRINCE | TME_KL_128,
- SIPHASH = TME_KT_Symmetric | TME_KAL_SIPHASH | TME_KL_128,
- KDF_NIST = TME_KT_Symmetric | TME_KAL_KDF_NIST | TME_KL_512,
- KDF_HKDF = TME_KT_Symmetric | TME_KAL_KDF_HKDF,
- /* Asymmetric Algorithms */
- ECDSA_P224_NIST = TME_KT_Asymmetric_ECC | TME_KAL_ECC_ALGO_ECDSA | TME_KL_224 |
- TME_KAL_ECC_CURVE_NIST,
- ECDSA_P256_NIST = TME_KT_Asymmetric_ECC | TME_KAL_ECC_ALGO_ECDSA | TME_KL_256 |
- TME_KAL_ECC_CURVE_NIST,
- ECDSA_P384_NIST = TME_KT_Asymmetric_ECC | TME_KAL_ECC_ALGO_ECDSA | TME_KL_384 |
- TME_KAL_ECC_CURVE_NIST,
- ECDSA_P521_NIST = TME_KT_Asymmetric_ECC | TME_KAL_ECC_ALGO_ECDSA | TME_KL_521 |
- TME_KAL_ECC_CURVE_NIST,
- ECDSA_P224_BP = TME_KT_Asymmetric_ECC | TME_KAL_ECC_ALGO_ECDSA | TME_KL_224 |
- TME_KAL_ECC_CURVE_BPOOL,
- ECDSA_P256_BP = TME_KT_Asymmetric_ECC | TME_KAL_ECC_ALGO_ECDSA | TME_KL_256 |
- TME_KAL_ECC_CURVE_BPOOL,
- ECDSA_P384_BP = TME_KT_Asymmetric_ECC | TME_KAL_ECC_ALGO_ECDSA | TME_KL_384 |
- TME_KAL_ECC_CURVE_BPOOL,
- ECDSA_P512_BP = TME_KT_Asymmetric_ECC | TME_KAL_ECC_ALGO_ECDSA | TME_KL_512 |
- TME_KAL_ECC_CURVE_BPOOL,
- ECDH_P224_NIST = TME_KT_Asymmetric_ECC | TME_KAL_ECC_ALGO_ECDH | TME_KL_224 |
- TME_KAL_ECC_CURVE_NIST,
- ECDH_P256_NIST = TME_KT_Asymmetric_ECC | TME_KAL_ECC_ALGO_ECDH | TME_KL_256 |
- TME_KAL_ECC_CURVE_NIST,
- ECDH_P384_NIST = TME_KT_Asymmetric_ECC | TME_KAL_ECC_ALGO_ECDH | TME_KL_384 |
- TME_KAL_ECC_CURVE_NIST,
- ECDH_P521_NIST = TME_KT_Asymmetric_ECC | TME_KAL_ECC_ALGO_ECDH | TME_KL_521 |
- TME_KAL_ECC_CURVE_NIST,
- ECDH_P224_BP = TME_KT_Asymmetric_ECC | TME_KAL_ECC_ALGO_ECDH | TME_KL_224 |
- TME_KAL_ECC_CURVE_BPOOL,
- ECDH_P256_BP = TME_KT_Asymmetric_ECC | TME_KAL_ECC_ALGO_ECDH | TME_KL_256 |
- TME_KAL_ECC_CURVE_BPOOL,
- ECDH_P384_BP = TME_KT_Asymmetric_ECC | TME_KAL_ECC_ALGO_ECDH | TME_KL_384 |
- TME_KAL_ECC_CURVE_BPOOL,
- ECDH_P512_BP = TME_KT_Asymmetric_ECC | TME_KAL_ECC_ALGO_ECDH | TME_KL_512 |
- TME_KAL_ECC_CURVE_BPOOL,
- HWKM_UNDEF_ALG = 0xFFFFFFFF
- };
- /* Key type values which can be used in the key_type field of the key policy */
- enum hwkm_type {
- KEY_DERIVATION_KEY = TME_KP_KeyDerivation,
- KEY_WRAPPING_KEY = TME_KP_KWK_STORAGE,
- KEY_SWAPPING_KEY = TME_KP_KWK_SESSION,
- TRANSPORT_KEY = TME_KP_KWK_TRANSPORT,
- GENERIC_KEY = TME_KP_Generic,
- EXPORT_KEY = TME_KP_KWK_XPORT,
- HWKM_UNDEF_KEY_TYPE = 0xFFFFFFFF
- };
- // TODO: Handle v3 vs v4 gracefully
- /* Destinations which a context can use */
- enum hwkm_destination {
- KM_MASTER = TME_KD_TME_HW_V4,
- GPCE_SLAVE = TME_KD_GPCE_V4,
- MCE_SLAVE = TME_KD_MDM_CE_V4,
- ICE_SLAVE = TME_KD_ICE_V4,
- ICEMEM_SLAVE = 10,
- HWKM_UNDEF_DESTINATION = 0xFFFFFFFF
- };
- /*
- * Key security levels which can be set in the security_lvl field of
- * key policy.
- */
- enum hwkm_security_level {
- /* Can be read by SW in plaintext using KEY_SLOT_RDWR cmd. */
- SW_KEY = TME_KSL_SWKey,
- /* Imported key managed by HW. */
- MANAGED_KEY = TME_KSL_ImportKey,
- /* Key only known to HW. */
- HW_KEY = TME_KSL_HWKey,
- HWKM_UNDEF_SECURITY_LEVEL = 0xFFFFFFFF
- };
- enum hwkm_key_lineage {
- KEY_LINEAGE_NA = TME_KLI_NA,
- KEY_LINEAGE_NOT_PROVISIONED_UNIQUE = TME_KLI_NP_CU,
- KEY_LINEAGE_NOT_PROVISIONED_NOT_UNIQUE = TME_KLI_P_NCU,
- KEY_LINEAGE_PROVISIONED_UNIQUE = TME_KLI_P_CU,
- HWKM_UNDEF_KEY_LINEAGE = 0xFFFFFFFF
- };
- #define HWKM_CRED_SLOT_NONE TME_CRED_SLOT_ID_NONE
- #define HWKM_CRED_SLOT_1 TME_CRED_SLOT_ID_1
- #define HWKM_CRED_SLOT_2 TME_CRED_SLOT_ID_2
- /** Slots 18-25 are reserved for use by TZ in the TME key table */
- enum hwkm_master_key_slots {
- /** L2 KDKs, used to derive keys by SW. Cannot be used for crypto, only key derivation */
- TZ_NKDK_L2 = TME_KID_CHIP_FAM_L1,
- TZ_PKDK_L2 = TME_KID_CHIP_UNIQUE_SEED,
- TZ_SKDK_L2 = TME_KID_CHIP_UNIQUE_SEED,
- TZ_UKDK_L2 = TME_KID_CHIP_RAND_BASE,
- /** Slots reserved for TPKEY */
- TPKEY_SLOT = TME_KID_TP,
- /** Slots reserved for Swap key */
- TZ_SWAP_KEY_SLOT = 18,
- /** Reserved for wrapping keys to persist or unwrap keys */
- TZ_WRAP_KEY_SLOT = 19,
- /** Reserved for intermediate operations in IHWKeyFactory */
- TZ_GENERAL_PURPOSE_SLOT1 = 20,
- TZ_GENERAL_PURPOSE_SLOT2 = 21,
- /** Reserved for mixing keys in KDF */
- TZ_MIXING_KEY_SLOT = 22,
- /** Used for asymmetric operations */
- TZ_ASYMMETRIC_OPERATION_SLOT = 23,
- /**
- * Reserved for privileged use cases which need to persist a key
- * and share it between execution environments.
- *
- * WARNING: Modifying these values may cause issues in execution
- * environments which depend on these specific slots being used for
- * privileged persistent use cases.
- */
- PERSISTENT_SHARED_SLOT_PAIR1 = 24,
- PERSISTENT_SHARED_SLOT_PAIR2 = 25,
- MASTER_SLOT_MAX,
- UNDEF_SLOT = 0xFF
- };
- struct hwkm_key_policy_v2_extension {
- bool expand_allowed;
- bool extract_allowed;
- enum hwkm_key_lineage lineage;
- u32 credential_slot;
- bool export_key_wrap_allowed;
- };
- #endif
- #if IS_ENABLED(CONFIG_QTI_HW_KEY_MANAGER_V1)
- enum hwkm_alg {
- AES128_ECB = 0,
- AES256_ECB = 1,
- DES_ECB = 2,
- TDES_ECB = 3,
- AES128_CBC = 4,
- AES256_CBC = 5,
- DES_CBC = 6,
- TDES_CBC = 7,
- AES128_CCM_TC = 8,
- AES128_CCM_NTC = 9,
- AES256_CCM_TC = 10,
- AES256_CCM_NTC = 11,
- AES256_SIV = 12,
- AES128_CTR = 13,
- AES256_CTR = 14,
- AES128_XTS = 15,
- AES256_XTS = 16,
- SHA1_HMAC = 17,
- SHA256_HMAC = 18,
- AES128_CMAC = 19,
- AES256_CMAC = 20,
- SHA384_HMAC = 21,
- SHA512_HMAC = 22,
- AES128_GCM = 23,
- AES256_GCM = 24,
- KASUMI = 25,
- SNOW3G = 26,
- ZUC = 27,
- PRINCE = 28,
- SIPHASH = 29,
- QARMA64 = 30,
- QARMA128 = 31,
- HWKM_ALG_MAX,
- HWKM_UNDEF_ALG = 0xFF
- };
- enum hwkm_type {
- KEY_DERIVATION_KEY = 0,
- KEY_WRAPPING_KEY = 1,
- KEY_SWAPPING_KEY = 2,
- TRANSPORT_KEY = 3,
- GENERIC_KEY = 4,
- HWKM_TYPE_MAX,
- HWKM_UNDEF_KEY_TYPE = 0xFF
- };
- /* Destinations which a context can use */
- enum hwkm_destination {
- KM_MASTER = 0,
- GPCE_SLAVE = 1,
- MCE_SLAVE = 2,
- PIMEM_SLAVE = 3,
- ICE0_SLAVE = 4,
- ICE1_SLAVE = 5,
- ICE2_SLAVE = 6,
- ICE3_SLAVE = 7,
- DP0_HDCP_SLAVE = 8,
- DP1_HDCP_SLAVE = 9,
- ICEMEM_SLAVE = 10,
- HWKM_DESTINATION_MAX,
- HWKM_UNDEF_DESTINATION = 0xFF
- };
- enum hwkm_security_level {
- /* Can be read by SW in plaintext using KEY_SLOT_RDWR cmd. */
- SW_KEY = 0,
- /* Usable by SW, but not readable in plaintext. */
- MANAGED_KEY = 1,
- /* Not usable by SW. */
- HW_KEY = 2,
- HWKM_SECURITY_LEVEL_MAX,
- HWKM_UNDEF_SECURITY_LEVEL = 0xFF
- };
- enum hwkm_master_key_slots {
- /** L1 KDKs. Not usable by SW. Used by HW to derive L2 KDKs */
- NKDK_L1 = 0,
- PKDK_L1 = 1,
- SKDK_L1 = 2,
- UKDK_L1 = 3,
- /*
- * L2 KDKs, used to derive keys by SW.
- * Cannot be used for crypto, only key derivation
- */
- TZ_NKDK_L2 = 4,
- TZ_PKDK_L2 = 5,
- TZ_SKDK_L2 = 6,
- MODEM_PKDK_L2 = 7,
- MODEM_SKDK_L2 = 8,
- TZ_UKDK_L2 = 9,
- /** Slots reserved for TPKEY */
- TPKEY_EVEN_SLOT = 10,
- TPKEY_KEY_ODD_SLOT = 11,
- /** First key slot available for general purpose use cases */
- MASTER_GENERIC_SLOTS_START,
- UNDEF_SLOT = 0xFF
- };
- #endif
- struct hwkm_key_policy {
- bool km_by_spu_allowed;
- bool km_by_modem_allowed;
- bool km_by_nsec_allowed;
- bool km_by_tz_allowed;
- enum hwkm_alg alg_allowed;
- bool enc_allowed;
- bool dec_allowed;
- enum hwkm_type key_type;
- u8 kdf_depth;
- bool wrap_export_allowed;
- bool swap_export_allowed;
- enum hwkm_security_level security_lvl;
- enum hwkm_destination hw_destination;
- bool wrap_with_tpk_allowed;
- #if IS_ENABLED(CONFIG_QTI_HW_KEY_MANAGER)
- struct hwkm_key_policy_v2_extension v2;
- #endif
- };
- struct hwkm_bsve {
- bool enabled;
- bool km_key_policy_ver_en;
- bool km_apps_secure_en;
- bool km_msa_secure_en;
- bool km_lcm_fuse_en;
- bool km_boot_stage_otp_en;
- bool km_swc_en;
- bool km_child_key_policy_en;
- bool km_mks_en;
- u64 km_fuse_region_sha_digest_en;
- #if IS_ENABLED(CONFIG_QTI_HW_KEY_MANAGER)
- bool km_oem_id_en;
- bool km_pkhash_en;
- bool km_oem_product_id_en;
- bool km_oem_product_seed_en;
- #endif
- };
- struct hwkm_keygen_cmd {
- u8 dks; /* Destination Key Slot */
- struct hwkm_key_policy policy; /* Key policy */
- };
- struct hwkm_rdwr_cmd {
- uint8_t slot; /* Key Slot */
- bool is_write; /* Write or read op */
- struct hwkm_key_policy policy; /* Key policy for write */
- uint8_t key[HWKM_MAX_KEY_SIZE]; /* Key for write */
- size_t sz; /* Length of key in bytes */
- };
- struct hwkm_kdf_cmd {
- uint8_t dks; /* Destination Key Slot */
- uint8_t kdk; /* Key Derivation Key Slot */
- uint8_t mks; /* Mixing key slot (bsve controlled) */
- struct hwkm_key_policy policy; /* Key policy. */
- struct hwkm_bsve bsve; /* Binding state vector */
- uint8_t ctx[HWKM_MAX_CTX_SIZE]; /* Context */
- size_t sz; /* Length of context in bytes */
- enum hwkm_alg parent_alg; /* Underlying KDF algorithm (required for TME) */
- };
- struct hwkm_set_tpkey_cmd {
- uint8_t sks; /* The slot to use as the TPKEY */
- };
- struct hwkm_unwrap_cmd {
- uint8_t dks; /* Destination Key Slot */
- uint8_t kwk; /* Key Wrapping Key Slot */
- uint8_t wkb[HWKM_MAX_BLOB_SIZE];/* Wrapped Key Blob */
- uint8_t sz; /* Length of WKB in bytes */
- };
- struct hwkm_wrap_cmd {
- uint8_t sks; /* Destination Key Slot */
- uint8_t kwk; /* Key Wrapping Key Slot */
- struct hwkm_bsve bsve; /* Binding state vector */
- };
- struct hwkm_clear_cmd {
- uint8_t dks; /* Destination key slot */
- bool is_double_key; /* Whether this is a double key */
- };
- struct hwkm_cmd {
- enum hwkm_op op; /* Operation */
- #if IS_ENABLED(CONFIG_QTI_HW_KEY_MANAGER)
- enum hwkm_destination dest;
- #endif
- union /* Structs with opcode specific parameters */
- {
- struct hwkm_keygen_cmd keygen;
- struct hwkm_rdwr_cmd rdwr;
- struct hwkm_kdf_cmd kdf;
- struct hwkm_set_tpkey_cmd set_tpkey;
- struct hwkm_unwrap_cmd unwrap;
- struct hwkm_wrap_cmd wrap;
- struct hwkm_clear_cmd clear;
- };
- };
- struct hwkm_rdwr_rsp {
- struct hwkm_key_policy policy; /* Key policy for read */
- uint8_t key[HWKM_MAX_KEY_SIZE]; /* Only available for read op */
- size_t sz; /* Length of the key (bytes) */
- };
- struct hwkm_wrap_rsp {
- uint8_t wkb[HWKM_MAX_BLOB_SIZE]; /* Wrapping key blob */
- size_t sz; /* key blob len (bytes) */
- };
- struct hwkm_rsp {
- u32 status;
- union /* Structs with opcode specific outputs */
- {
- struct hwkm_rdwr_rsp rdwr;
- struct hwkm_wrap_rsp wrap;
- };
- };
- #if (IS_ENABLED(CONFIG_QTI_HW_KEY_MANAGER) || IS_ENABLED(CONFIG_QTI_HW_KEY_MANAGER_V1))
- int qti_hwkm_handle_cmd(struct hwkm_cmd *cmd, struct hwkm_rsp *rsp);
- int qti_hwkm_clocks(bool on);
- int qti_hwkm_init(const struct ice_mmio_data *mmio_data);
- #else
- static inline int qti_hwkm_add_req(struct hwkm_cmd *cmd,
- struct hwkm_rsp *rsp)
- {
- return -EOPNOTSUPP;
- }
- static inline int qti_hwkm_clocks(bool on)
- {
- return -EOPNOTSUPP;
- }
- static inline int qti_hwkm_init(const struct ice_mmio_data *mmio_data)
- {
- return -EOPNOTSUPP;
- }
- #endif /* CONFIG_QTI_HW_KEY_MANAGER */
- #endif /* __HWKM_H_ */
|