100565589SLin Jinhan /* SPDX-License-Identifier: GPL-2.0 */ 200565589SLin Jinhan 300565589SLin Jinhan /* Copyright (c) 2025 Rockchip Electronics Co., Ltd. */ 400565589SLin Jinhan 500565589SLin Jinhan #ifndef __RKCE_CORE_H__ 600565589SLin Jinhan #define __RKCE_CORE_H__ 700565589SLin Jinhan 800565589SLin Jinhan #include <linux/bitops.h> 900565589SLin Jinhan #include <linux/types.h> 1000565589SLin Jinhan 1100565589SLin Jinhan #include "rkce_buf.h" 1200565589SLin Jinhan #include "rkce_error.h" 1300565589SLin Jinhan #include "rkce_reg.h" 1400565589SLin Jinhan 1500565589SLin Jinhan #define RKCE_TD_SG_NUM 8 1600565589SLin Jinhan 1700565589SLin Jinhan #define RKCE_AES_BLOCK_SIZE 16 1800565589SLin Jinhan #define RKCE_AES_KEYSIZE_128 16 1900565589SLin Jinhan #define RKCE_AES_KEYSIZE_192 24 2000565589SLin Jinhan #define RKCE_AES_KEYSIZE_256 32 2100565589SLin Jinhan 2200565589SLin Jinhan #define RKCE_SM4_KEYSIZE 16 2300565589SLin Jinhan 2400565589SLin Jinhan #define RKCE_DES_BLOCK_SIZE 8 2500565589SLin Jinhan #define RKCE_DES_KEYSIZE 8 2600565589SLin Jinhan #define RKCE_TDES_EDE_KEYSIZE 24 2700565589SLin Jinhan 2800565589SLin Jinhan #define RKCE_TD_ALIGINMENT 16 2900565589SLin Jinhan #define RKCE_TD_KEY_SIZE 128 3000565589SLin Jinhan #define RKCE_TD_IV_SIZE 16 3100565589SLin Jinhan #define RKCE_TD_GCM_LEN_SIZE 16 3200565589SLin Jinhan #define RKCE_TD_HASH_CTX_SIZE RKCE_HASH_CONTEXT_SIZE 3300565589SLin Jinhan #define RKCE_TD_SYMM_CTX_SIZE RKCE_SYMM_CONTEXT_SIZE 3400565589SLin Jinhan #define RKCE_TD_TAG_SIZE 16 3500565589SLin Jinhan #define RKCE_TD_TAG_SIZE_MIN 8 3600565589SLin Jinhan #define RKCE_TD_TAG_SIZE_MAX RKCE_TD_TAG_SIZE 3700565589SLin Jinhan #define RKCE_TD_HASH_SIZE 64 3800565589SLin Jinhan #define RKCE_TD_FIFO_DEPTH 8 3900565589SLin Jinhan 4000565589SLin Jinhan #define RKCE_RESET_SYMM BIT(0) 4100565589SLin Jinhan #define RKCE_RESET_HASH BIT(1) 4200565589SLin Jinhan #define RKCE_RESET_PKA BIT(2) 4300565589SLin Jinhan #define RKCE_RESET_ALL (RKCE_RESET_SYMM | RKCE_RESET_HASH | RKCE_RESET_PKA) 4400565589SLin Jinhan 4500565589SLin Jinhan #define RKCE_WRITE_MASK_SHIFT (16) 4600565589SLin Jinhan #define RKCE_WRITE_MASK_ALL ((0xffffu << RKCE_WRITE_MASK_SHIFT)) 4700565589SLin Jinhan 4800565589SLin Jinhan enum rkce_expand_bit { 4900565589SLin Jinhan RKCE_EXPAND_BIT_4G = 0, 5000565589SLin Jinhan RKCE_EXPAND_BIT_8G, 5100565589SLin Jinhan RKCE_EXPAND_BIT_16G, 5200565589SLin Jinhan RKCE_EXPAND_BIT_32G, 5300565589SLin Jinhan }; 5400565589SLin Jinhan 5500565589SLin Jinhan enum rkce_td_type { 5600565589SLin Jinhan RKCE_TD_TYPE_SYMM = 0, 5700565589SLin Jinhan RKCE_TD_TYPE_HASH, 5800565589SLin Jinhan RKCE_TD_TYPE_SYMM_HASH_IN, 5900565589SLin Jinhan RKCE_TD_TYPE_SYMM_HASH_OUT, 6000565589SLin Jinhan RKCE_TD_TYPE_MAX, 6100565589SLin Jinhan }; 6200565589SLin Jinhan 6300565589SLin Jinhan enum rkce_algo_symm_type { 6400565589SLin Jinhan RKCE_SYMM_ALGO_AES = 0, 6500565589SLin Jinhan RKCE_SYMM_ALGO_SM4, 6600565589SLin Jinhan RKCE_SYMM_ALGO_DES, 6700565589SLin Jinhan RKCE_SYMM_ALGO_TDES, 6800565589SLin Jinhan RKCE_SYMM_ALGO_MAX, 6900565589SLin Jinhan }; 7000565589SLin Jinhan 7100565589SLin Jinhan enum rkce_algo_symm_mode { 7200565589SLin Jinhan RKCE_SYMM_MODE_ECB = 0, 7300565589SLin Jinhan RKCE_SYMM_MODE_CBC, 7400565589SLin Jinhan RKCE_SYMM_MODE_CTS, 7500565589SLin Jinhan RKCE_SYMM_MODE_CTR, 7600565589SLin Jinhan RKCE_SYMM_MODE_CFB, 7700565589SLin Jinhan RKCE_SYMM_MODE_OFB, 7800565589SLin Jinhan RKCE_SYMM_MODE_XTS, 7900565589SLin Jinhan RKCE_SYMM_MODE_CCM, 8000565589SLin Jinhan RKCE_SYMM_MODE_GCM, 8100565589SLin Jinhan RKCE_SYMM_MODE_CMAC, 8200565589SLin Jinhan RKCE_SYMM_MODE_CBC_MAC, 8300565589SLin Jinhan RKCE_SYMM_MODE_BYPASS = 0xf, 8400565589SLin Jinhan RKCE_SYMM_MODE_MAX, 8500565589SLin Jinhan }; 8600565589SLin Jinhan 8700565589SLin Jinhan enum { 8800565589SLin Jinhan RKCE_KEY_AES_128 = 0, 8900565589SLin Jinhan RKCE_KEY_AES_192, 9000565589SLin Jinhan RKCE_KEY_AES_256, 9100565589SLin Jinhan }; 9200565589SLin Jinhan 93*8f7f431fSTroy Lin enum { 94*8f7f431fSTroy Lin RKCE_KEY_SEL_USER = 0, 95*8f7f431fSTroy Lin RKCE_KEY_SEL_KT = 1, 96*8f7f431fSTroy Lin RKCE_KEY_SEL_KL_KA = 4, 97*8f7f431fSTroy Lin RKCE_KEY_SEL_KL_K1, 98*8f7f431fSTroy Lin RKCE_KEY_SEL_KL_K2, 99*8f7f431fSTroy Lin RKCE_KEY_SEL_KL_K3, 100*8f7f431fSTroy Lin }; 101*8f7f431fSTroy Lin 10200565589SLin Jinhan enum rkce_algo_hash_type { 10300565589SLin Jinhan RKCE_HASH_ALGO_SHA1 = 0, 10400565589SLin Jinhan RKCE_HASH_ALGO_MD5, 10500565589SLin Jinhan RKCE_HASH_ALGO_SHA256, 10600565589SLin Jinhan RKCE_HASH_ALGO_SHA224, 10700565589SLin Jinhan RKCE_HASH_ALGO_SM3 = 6, 10800565589SLin Jinhan RKCE_HASH_ALGO_SHA512 = 8, 10900565589SLin Jinhan RKCE_HASH_ALGO_SHA384 = 9, 11000565589SLin Jinhan RKCE_HASH_ALGO_SHA512_224, 11100565589SLin Jinhan RKCE_HASH_ALGO_SHA512_256, 11200565589SLin Jinhan RKCE_HASH_ALGO_MAX, 11300565589SLin Jinhan }; 11400565589SLin Jinhan 11500565589SLin Jinhan enum rkce_algo_asym_type { 11600565589SLin Jinhan RKCE_ASYM_ALGO_RSA = 0, 11700565589SLin Jinhan RKCE_ASYM_ALGO_ECC_P192, 11800565589SLin Jinhan RKCE_ASYM_ALGO_ECC_P224, 11900565589SLin Jinhan RKCE_ASYM_ALGO_ECC_P256, 12000565589SLin Jinhan RKCE_ASYM_ALGO_ECC_P384, 12100565589SLin Jinhan RKCE_ASYM_ALGO_ECC_P521, 12200565589SLin Jinhan RKCE_ASYM_ALGO_SM2, 12300565589SLin Jinhan RKCE_ASYM_ALGO_MAX, 12400565589SLin Jinhan }; 12500565589SLin Jinhan 12600565589SLin Jinhan enum rkce_algo_type { 12700565589SLin Jinhan RKCE_ALGO_TYPE_HASH, 12800565589SLin Jinhan RKCE_ALGO_TYPE_HMAC, 12900565589SLin Jinhan RKCE_ALGO_TYPE_CIPHER, 13000565589SLin Jinhan RKCE_ALGO_TYPE_ASYM, 13100565589SLin Jinhan RKCE_ALGO_TYPE_AEAD, 13200565589SLin Jinhan RKCE_ALGO_TYPE_MAX, 13300565589SLin Jinhan }; 13400565589SLin Jinhan 13500565589SLin Jinhan struct rkce_ip_info { 13600565589SLin Jinhan uint32_t aes_ver; 13700565589SLin Jinhan uint32_t des_ver; 13800565589SLin Jinhan uint32_t sm4_ver; 13900565589SLin Jinhan uint32_t hash_ver; 14000565589SLin Jinhan uint32_t hmac_ver; 14100565589SLin Jinhan uint32_t pka_ver; 14200565589SLin Jinhan uint32_t extra_feature; 14300565589SLin Jinhan uint32_t ce_ver; 14400565589SLin Jinhan }; 14500565589SLin Jinhan 14600565589SLin Jinhan struct rkce_gcm_len { 14700565589SLin Jinhan uint32_t pc_len_l; 14800565589SLin Jinhan uint32_t pc_len_h; 14900565589SLin Jinhan uint32_t aad_len_l; 15000565589SLin Jinhan uint32_t aad_len_h; 15100565589SLin Jinhan }; 15200565589SLin Jinhan 15300565589SLin Jinhan struct rkce_sg_info { 15400565589SLin Jinhan uint32_t src_size; 15500565589SLin Jinhan uint32_t src_addr_h; 15600565589SLin Jinhan uint32_t src_addr_l; 15700565589SLin Jinhan 15800565589SLin Jinhan uint32_t dst_size; 15900565589SLin Jinhan uint32_t dst_addr_h; 16000565589SLin Jinhan uint32_t dst_addr_l; 16100565589SLin Jinhan }; 16200565589SLin Jinhan 16300565589SLin Jinhan /* total = 64 + 16 + 16 + 16 + 32 = 114(Byte) */ 16400565589SLin Jinhan struct rkce_symm_td_buf { 16500565589SLin Jinhan uint8_t key1[RKCE_AES_KEYSIZE_256]; // offset 0x00 16600565589SLin Jinhan uint8_t key2[RKCE_AES_KEYSIZE_256]; // offset 0x20 16700565589SLin Jinhan uint8_t iv[RKCE_TD_IV_SIZE]; // offset 0x40 16800565589SLin Jinhan struct rkce_gcm_len gcm_len; // offset 0x50 16900565589SLin Jinhan uint8_t tag[RKCE_TD_TAG_SIZE]; // offset 0x60 17000565589SLin Jinhan uint8_t ctx[RKCE_SYMM_CONTEXT_SIZE]; // offset 0x70 17100565589SLin Jinhan void *user_data; 17200565589SLin Jinhan }; 17300565589SLin Jinhan 17400565589SLin Jinhan /* total = 128 + 64 + 208 = 360(Byte) */ 17500565589SLin Jinhan struct rkce_hash_td_buf { 17600565589SLin Jinhan uint8_t key[RKCE_TD_KEY_SIZE]; // offset 0x00 17700565589SLin Jinhan uint8_t hash[RKCE_TD_HASH_SIZE]; // offset 0x80 17800565589SLin Jinhan uint8_t ctx[RKCE_HASH_CONTEXT_SIZE]; // offset 0xB0 17900565589SLin Jinhan void *user_data; 18000565589SLin Jinhan }; 18100565589SLin Jinhan 18200565589SLin Jinhan struct rkce_symm_hash_td_buf { 18300565589SLin Jinhan uint8_t key1[RKCE_AES_KEYSIZE_256]; // offset 0x00 18400565589SLin Jinhan uint8_t key2[RKCE_AES_KEYSIZE_256]; // offset 0x20 18500565589SLin Jinhan uint8_t key3[RKCE_AES_KEYSIZE_256 * 2]; // offset 0x40 18600565589SLin Jinhan uint8_t iv[RKCE_TD_IV_SIZE]; // offset 0x80 18700565589SLin Jinhan struct rkce_gcm_len gcm_len; // offset 0x90 18800565589SLin Jinhan uint8_t tag[RKCE_TD_TAG_SIZE]; // offset 0xA0 18900565589SLin Jinhan uint8_t hash[RKCE_TD_HASH_SIZE]; // offset 0xB0 19000565589SLin Jinhan uint8_t symm_ctx[RKCE_SYMM_CONTEXT_SIZE]; // offset 0xF0 19100565589SLin Jinhan uint8_t hash_ctx[RKCE_HASH_CONTEXT_SIZE]; // offset 0x110 19200565589SLin Jinhan void *user_data; 19300565589SLin Jinhan }; 19400565589SLin Jinhan 19500565589SLin Jinhan struct rkce_symm_td_ctrl { 19600565589SLin Jinhan uint32_t td_type : 2; 19700565589SLin Jinhan uint32_t is_dec : 1; 19800565589SLin Jinhan uint32_t is_aad : 1; 19900565589SLin Jinhan uint32_t symm_algo : 2; 20000565589SLin Jinhan uint32_t : 2; 20100565589SLin Jinhan uint32_t symm_mode : 4; 20200565589SLin Jinhan uint32_t key_size : 2; 20300565589SLin Jinhan uint32_t first_pkg : 1; 20400565589SLin Jinhan uint32_t last_pkg : 1; 20500565589SLin Jinhan uint32_t key_sel : 3; 20600565589SLin Jinhan uint32_t iv_len : 5; 20700565589SLin Jinhan uint32_t : 4; 20800565589SLin Jinhan uint32_t is_key_inside : 1; 20900565589SLin Jinhan uint32_t : 1; 21000565589SLin Jinhan uint32_t is_preemptible : 1; 21100565589SLin Jinhan uint32_t int_en : 1; 21200565589SLin Jinhan }; 21300565589SLin Jinhan 21400565589SLin Jinhan struct rkce_hash_td_ctrl { 21500565589SLin Jinhan uint32_t td_type : 2; 21600565589SLin Jinhan uint32_t : 5; 21700565589SLin Jinhan uint32_t hw_pad_en : 1; 21800565589SLin Jinhan uint32_t : 6; 21900565589SLin Jinhan uint32_t first_pkg : 1; 22000565589SLin Jinhan uint32_t last_pkg : 1; 22100565589SLin Jinhan uint32_t : 8; 22200565589SLin Jinhan uint32_t hash_algo: 4; 22300565589SLin Jinhan uint32_t : 1; 22400565589SLin Jinhan uint32_t hmac_en : 1; 22500565589SLin Jinhan uint32_t is_preemptible : 1; 22600565589SLin Jinhan uint32_t int_en : 1; 22700565589SLin Jinhan }; 22800565589SLin Jinhan 22900565589SLin Jinhan struct rkce_symm_hash_td_ctrl { 23000565589SLin Jinhan uint32_t td_type : 2; 23100565589SLin Jinhan uint32_t is_dec : 1; 23200565589SLin Jinhan uint32_t is_aad : 1; 23300565589SLin Jinhan uint32_t symm_algo : 2; 23400565589SLin Jinhan uint32_t : 1; 23500565589SLin Jinhan uint32_t hw_pad_en : 1; 23600565589SLin Jinhan uint32_t symm_mode : 4; 23700565589SLin Jinhan uint32_t key_size : 2; 23800565589SLin Jinhan uint32_t first_pkg : 1; 23900565589SLin Jinhan uint32_t last_pkg : 1; 24000565589SLin Jinhan uint32_t key_sel : 3; 24100565589SLin Jinhan uint32_t iv_len : 5; 24200565589SLin Jinhan uint32_t hash_algo: 4; 24300565589SLin Jinhan uint32_t is_key_inside : 1; 24400565589SLin Jinhan uint32_t hmac_en : 1; 24500565589SLin Jinhan uint32_t is_preemptible : 1; 24600565589SLin Jinhan uint32_t int_en : 1; 24700565589SLin Jinhan }; 24800565589SLin Jinhan 24900565589SLin Jinhan struct rkce_symm_td { 25000565589SLin Jinhan uint32_t task_id; 25100565589SLin Jinhan struct rkce_symm_td_ctrl ctrl; 25200565589SLin Jinhan uint32_t reserve1; 25300565589SLin Jinhan uint32_t key_addr; 25400565589SLin Jinhan 25500565589SLin Jinhan uint32_t iv_addr; 25600565589SLin Jinhan uint32_t gcm_len_addr; 25700565589SLin Jinhan uint32_t reserve2; 25800565589SLin Jinhan uint32_t tag_addr; 25900565589SLin Jinhan 26000565589SLin Jinhan struct rkce_sg_info sg[RKCE_TD_SG_NUM]; 26100565589SLin Jinhan 26200565589SLin Jinhan uint32_t reserve3; 26300565589SLin Jinhan uint32_t symm_ctx_addr; 26400565589SLin Jinhan uint32_t reserve4[5]; 26500565589SLin Jinhan uint32_t next_task; 26600565589SLin Jinhan }; 26700565589SLin Jinhan 26800565589SLin Jinhan struct rkce_hash_td { 26900565589SLin Jinhan uint32_t task_id; 27000565589SLin Jinhan struct rkce_hash_td_ctrl ctrl; 27100565589SLin Jinhan uint32_t reserve1; 27200565589SLin Jinhan uint32_t key_addr; 27300565589SLin Jinhan 27400565589SLin Jinhan uint32_t reserve2[2]; 27500565589SLin Jinhan uint32_t hash_addr; 27600565589SLin Jinhan uint32_t reserve3; 27700565589SLin Jinhan 27800565589SLin Jinhan struct rkce_sg_info sg[RKCE_TD_SG_NUM]; 27900565589SLin Jinhan 28000565589SLin Jinhan uint32_t hash_ctx_addr; 28100565589SLin Jinhan uint32_t reserve4[6]; 28200565589SLin Jinhan uint32_t next_task; 28300565589SLin Jinhan }; 28400565589SLin Jinhan 28500565589SLin Jinhan struct rkce_symm_hash_td { 28600565589SLin Jinhan uint32_t task_id; 28700565589SLin Jinhan struct rkce_symm_hash_td_ctrl ctrl; 28800565589SLin Jinhan uint32_t reserve1; 28900565589SLin Jinhan uint32_t key_addr; 29000565589SLin Jinhan 29100565589SLin Jinhan uint32_t iv_addr; 29200565589SLin Jinhan uint32_t gcm_len_addr; 29300565589SLin Jinhan uint32_t hash_addr; 29400565589SLin Jinhan uint32_t tag_addr; 29500565589SLin Jinhan 29600565589SLin Jinhan struct rkce_sg_info sg[RKCE_TD_SG_NUM]; 29700565589SLin Jinhan 29800565589SLin Jinhan uint32_t hash_ctx_addr; 29900565589SLin Jinhan uint32_t symm_ctx_addr; 30000565589SLin Jinhan uint32_t reserve3[5]; 30100565589SLin Jinhan uint32_t next_task; 30200565589SLin Jinhan }; 30300565589SLin Jinhan 30400565589SLin Jinhan struct rkce_td { 30500565589SLin Jinhan union { 30600565589SLin Jinhan struct rkce_symm_td symm; 30700565589SLin Jinhan struct rkce_hash_td hash; 30800565589SLin Jinhan struct rkce_symm_hash_td symm_hash; 30900565589SLin Jinhan } td; 31000565589SLin Jinhan }; 31100565589SLin Jinhan 31200565589SLin Jinhan struct rkce_td_buf { 31300565589SLin Jinhan union { 31400565589SLin Jinhan struct rkce_symm_td_buf symm; 31500565589SLin Jinhan struct rkce_hash_td_buf hash; 31600565589SLin Jinhan struct rkce_symm_hash_td_buf symm_hash; 31700565589SLin Jinhan } td_buf; 31800565589SLin Jinhan }; 31900565589SLin Jinhan 32000565589SLin Jinhan typedef int (*request_cb_func)(int result, uint32_t td_id, void *td_virt); 32100565589SLin Jinhan 32200565589SLin Jinhan void rkce_dump_reginfo(void *rkce_hw); 32300565589SLin Jinhan 32400565589SLin Jinhan void *rkce_hardware_alloc(void __iomem *reg_base); 32500565589SLin Jinhan 32600565589SLin Jinhan void rkce_hardware_free(void *rkce_hw); 32700565589SLin Jinhan 32800565589SLin Jinhan void rkce_irq_handler(void *rkce_hw); 32900565589SLin Jinhan 33000565589SLin Jinhan void rkce_irq_thread(void *rkce_hw); 33100565589SLin Jinhan 33200565589SLin Jinhan int rkce_irq_callback_set(void *rkce_hw, enum rkce_td_type td_type, request_cb_func cb_func); 33300565589SLin Jinhan 33400565589SLin Jinhan int rkce_soft_reset(void *rkce_hw, uint32_t reset_sel); 33500565589SLin Jinhan 33600565589SLin Jinhan int rkce_push_td(void *rkce_hw, void *td); 33700565589SLin Jinhan 33800565589SLin Jinhan int rkce_push_td_sync(void *rkce_hw, void *td, uint32_t timeout_ms); 33900565589SLin Jinhan 34000565589SLin Jinhan uint32_t rkce_get_td_type(void *td_buf); 34100565589SLin Jinhan 34200565589SLin Jinhan int rkce_init_symm_td(struct rkce_symm_td *td, struct rkce_symm_td_buf *buf); 34300565589SLin Jinhan 34400565589SLin Jinhan int rkce_init_hash_td(struct rkce_hash_td *td, struct rkce_hash_td_buf *buf); 34500565589SLin Jinhan 34600565589SLin Jinhan bool rkce_hw_algo_valid(void *rkce_hw, uint32_t type, uint32_t algo, uint32_t mode); 34700565589SLin Jinhan 348*8f7f431fSTroy Lin uint32_t rkce_get_keytable_addr(void *rkce_hw); 349*8f7f431fSTroy Lin 35000565589SLin Jinhan #endif 351