1b353a43cSLin Jinhan // SPDX-License-Identifier: GPL-2.0 2b353a43cSLin Jinhan /* 3b353a43cSLin Jinhan * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd 4b353a43cSLin Jinhan */ 5b353a43cSLin Jinhan 6b353a43cSLin Jinhan #include <common.h> 7b353a43cSLin Jinhan #include <clk.h> 8b353a43cSLin Jinhan #include <crypto.h> 9b353a43cSLin Jinhan #include <dm.h> 10b353a43cSLin Jinhan #include <asm/io.h> 11dd7763a8SFinley Xiao #include <clk-uclass.h> 12b353a43cSLin Jinhan #include <asm/arch/hardware.h> 13b353a43cSLin Jinhan #include <asm/arch/clock.h> 1402b4cf42SLin Jinhan #include <rockchip/crypto_ecc.h> 15c48f1acfSLin Jinhan #include <rockchip/crypto_hash_cache.h> 16b353a43cSLin Jinhan #include <rockchip/crypto_v2.h> 17b353a43cSLin Jinhan #include <rockchip/crypto_v2_pka.h> 18b353a43cSLin Jinhan 19c48f1acfSLin Jinhan #define RK_HASH_CTX_MAGIC 0x1A1A1A1A 20c48f1acfSLin Jinhan 21e0c259feSLin Jinhan #define CRYPTO_MAJOR_VER(ver) ((ver) & 0x0f000000) 22e0c259feSLin Jinhan 23e0c259feSLin Jinhan #define CRYPTO_MAJOR_VER_3 0x03000000 24e0c259feSLin Jinhan #define CRYPTO_MAJOR_VER_4 0x04000000 253cbec420SJoseph Chen #ifdef CONFIG_ROCKCHIP_RK3562 263cbec420SJoseph Chen #define CRYPTO_S_BY_KEYLAD_BASE 0xFF8A8000 273cbec420SJoseph Chen #endif 28e0c259feSLin Jinhan 2949a2135eSLin Jinhan #ifdef DEBUG 3049a2135eSLin Jinhan #define IMSG(format, ...) printf("[%s, %05d]-trace: " format "\n", \ 3149a2135eSLin Jinhan __func__, __LINE__, ##__VA_ARGS__) 3249a2135eSLin Jinhan #else 3349a2135eSLin Jinhan #define IMSG(format, ...) 3449a2135eSLin Jinhan #endif 35c48f1acfSLin Jinhan 36c48f1acfSLin Jinhan struct crypto_lli_desc { 37c48f1acfSLin Jinhan u32 src_addr; 38c48f1acfSLin Jinhan u32 src_len; 39c48f1acfSLin Jinhan u32 dst_addr; 40c48f1acfSLin Jinhan u32 dst_len; 41c48f1acfSLin Jinhan u32 user_define; 42c48f1acfSLin Jinhan u32 reserve; 43c48f1acfSLin Jinhan u32 dma_ctrl; 44c48f1acfSLin Jinhan u32 next_addr; 45c48f1acfSLin Jinhan }; 46c48f1acfSLin Jinhan 47c48f1acfSLin Jinhan struct rk_hash_ctx { 48c48f1acfSLin Jinhan struct crypto_lli_desc data_lli; /* lli desc */ 49c48f1acfSLin Jinhan struct crypto_hash_cache *hash_cache; 50c48f1acfSLin Jinhan u32 magic; /* to check ctx */ 51c48f1acfSLin Jinhan u32 algo; /* hash algo */ 52c48f1acfSLin Jinhan u8 digest_size; /* hash out length */ 53c48f1acfSLin Jinhan u8 reserved[3]; 54c48f1acfSLin Jinhan }; 55c48f1acfSLin Jinhan 5649a2135eSLin Jinhan struct rk_crypto_soc_data { 5749a2135eSLin Jinhan u32 capability; 5858432b6fSLin Jinhan u32 (*dynamic_cap)(void); 5949a2135eSLin Jinhan }; 6049a2135eSLin Jinhan 61b353a43cSLin Jinhan struct rockchip_crypto_priv { 62b353a43cSLin Jinhan fdt_addr_t reg; 63b353a43cSLin Jinhan u32 frequency; 64b353a43cSLin Jinhan char *clocks; 65b353a43cSLin Jinhan u32 *frequencies; 66b353a43cSLin Jinhan u32 nclocks; 67da703fb5SLin Jinhan u32 freq_nclocks; 68b353a43cSLin Jinhan u32 length; 691606a214SLin Jinhan struct rk_hash_ctx *hw_ctx; 7049a2135eSLin Jinhan struct rk_crypto_soc_data *soc_data; 71b353a43cSLin Jinhan }; 72b353a43cSLin Jinhan 7349a2135eSLin Jinhan #define LLI_ADDR_ALIGN_SIZE 8 7449a2135eSLin Jinhan #define DATA_ADDR_ALIGN_SIZE 8 7549a2135eSLin Jinhan #define DATA_LEN_ALIGN_SIZE 64 761606a214SLin Jinhan 77086e8fa8SLin Jinhan /* crypto timeout 500ms, must support more than 32M data per times*/ 78086e8fa8SLin Jinhan #define HASH_UPDATE_LIMIT (32 * 1024 * 1024) 7949a2135eSLin Jinhan #define RK_CRYPTO_TIMEOUT 500000 80b353a43cSLin Jinhan 8149a2135eSLin Jinhan #define RK_POLL_TIMEOUT(condition, timeout) \ 8249a2135eSLin Jinhan ({ \ 8349a2135eSLin Jinhan int time_out = timeout; \ 84b353a43cSLin Jinhan while (condition) { \ 8549a2135eSLin Jinhan if (--time_out <= 0) { \ 861606a214SLin Jinhan debug("[%s] %d: time out!\n", __func__,\ 87b353a43cSLin Jinhan __LINE__); \ 88b353a43cSLin Jinhan break; \ 89b353a43cSLin Jinhan } \ 90b353a43cSLin Jinhan udelay(1); \ 91b353a43cSLin Jinhan } \ 9249a2135eSLin Jinhan (time_out <= 0) ? -ETIMEDOUT : 0; \ 9349a2135eSLin Jinhan }) 94b353a43cSLin Jinhan 95d9332f1cSLin Jinhan #define WAIT_TAG_VALID(channel, timeout) ({ \ 96d9332f1cSLin Jinhan u32 tag_mask = CRYPTO_CH0_TAG_VALID << (channel);\ 97e0c259feSLin Jinhan int ret = 0;\ 98e0c259feSLin Jinhan if (is_check_tag_valid()) { \ 99d9332f1cSLin Jinhan ret = RK_POLL_TIMEOUT(!(crypto_read(CRYPTO_TAG_VALID) & tag_mask),\ 100d9332f1cSLin Jinhan timeout);\ 101e0c259feSLin Jinhan } \ 102d9332f1cSLin Jinhan crypto_write(crypto_read(CRYPTO_TAG_VALID) & tag_mask, CRYPTO_TAG_VALID);\ 103d9332f1cSLin Jinhan ret;\ 104d9332f1cSLin Jinhan }) 105d9332f1cSLin Jinhan 106b353a43cSLin Jinhan #define virt_to_phys(addr) (((unsigned long)addr) & 0xffffffff) 107b353a43cSLin Jinhan #define phys_to_virt(addr, area) ((unsigned long)addr) 108b353a43cSLin Jinhan 10949a2135eSLin Jinhan #define align_malloc(bytes, alignment) memalign(alignment, bytes) 110dbca2fe7SLin Jinhan #define align_free(addr) do {if (addr) free(addr);} while (0) 11149a2135eSLin Jinhan 11249a2135eSLin Jinhan #define ROUNDUP(size, alignment) round_up(size, alignment) 11349a2135eSLin Jinhan #define cache_op_inner(type, addr, size) \ 11449a2135eSLin Jinhan crypto_flush_cacheline((ulong)addr, size) 11549a2135eSLin Jinhan 116d9332f1cSLin Jinhan #define IS_NEED_IV(rk_mode) ((rk_mode) != RK_MODE_ECB && \ 117d9332f1cSLin Jinhan (rk_mode) != RK_MODE_CMAC && \ 118d9332f1cSLin Jinhan (rk_mode) != RK_MODE_CBC_MAC) 119d9332f1cSLin Jinhan 120d9332f1cSLin Jinhan #define IS_NEED_TAG(rk_mode) ((rk_mode) == RK_MODE_CMAC || \ 121c3ce9937SLin Jinhan (rk_mode) == RK_MODE_CBC_MAC || \ 122c3ce9937SLin Jinhan (rk_mode) == RK_MODE_CCM || \ 123c3ce9937SLin Jinhan (rk_mode) == RK_MODE_GCM) 124d9332f1cSLin Jinhan 125d9332f1cSLin Jinhan #define IS_MAC_MODE(rk_mode) ((rk_mode) == RK_MODE_CMAC || \ 126d9332f1cSLin Jinhan (rk_mode) == RK_MODE_CBC_MAC) 127d9332f1cSLin Jinhan 128c3ce9937SLin Jinhan #define IS_AE_MODE(rk_mode) ((rk_mode) == RK_MODE_CCM || \ 129c3ce9937SLin Jinhan (rk_mode) == RK_MODE_GCM) 130c3ce9937SLin Jinhan 131b353a43cSLin Jinhan fdt_addr_t crypto_base; 132e0c259feSLin Jinhan static uint32_t g_crypto_version; 133e0c259feSLin Jinhan 134e0c259feSLin Jinhan static inline bool is_check_hash_valid(void) 135e0c259feSLin Jinhan { 136e0c259feSLin Jinhan /* crypto < v4 need to check hash valid */ 137e0c259feSLin Jinhan return CRYPTO_MAJOR_VER(g_crypto_version) < CRYPTO_MAJOR_VER_4; 138e0c259feSLin Jinhan } 139e0c259feSLin Jinhan 140e0c259feSLin Jinhan static inline bool is_check_tag_valid(void) 141e0c259feSLin Jinhan { 142e0c259feSLin Jinhan /* crypto < v4 need to check hash valid */ 143e0c259feSLin Jinhan return CRYPTO_MAJOR_VER(g_crypto_version) < CRYPTO_MAJOR_VER_4; 144e0c259feSLin Jinhan } 145b353a43cSLin Jinhan 14649a2135eSLin Jinhan static inline void word2byte_be(u32 word, u8 *ch) 147b353a43cSLin Jinhan { 148b353a43cSLin Jinhan ch[0] = (word >> 24) & 0xff; 149b353a43cSLin Jinhan ch[1] = (word >> 16) & 0xff; 150b353a43cSLin Jinhan ch[2] = (word >> 8) & 0xff; 151b353a43cSLin Jinhan ch[3] = (word >> 0) & 0xff; 152b353a43cSLin Jinhan } 153b353a43cSLin Jinhan 15449a2135eSLin Jinhan static inline u32 byte2word_be(const u8 *ch) 15549a2135eSLin Jinhan { 15649a2135eSLin Jinhan return (*ch << 24) + (*(ch + 1) << 16) + (*(ch + 2) << 8) + *(ch + 3); 15749a2135eSLin Jinhan } 15849a2135eSLin Jinhan 15949a2135eSLin Jinhan static inline void clear_regs(u32 base, u32 words) 160b353a43cSLin Jinhan { 161b353a43cSLin Jinhan int i; 162b353a43cSLin Jinhan 163b353a43cSLin Jinhan /*clear out register*/ 16449a2135eSLin Jinhan for (i = 0; i < words; i++) 16549a2135eSLin Jinhan crypto_write(0, base + 4 * i); 16649a2135eSLin Jinhan } 16749a2135eSLin Jinhan 16849a2135eSLin Jinhan static inline void clear_key_regs(void) 16949a2135eSLin Jinhan { 17049a2135eSLin Jinhan clear_regs(CRYPTO_CH0_KEY_0, CRYPTO_KEY_CHANNEL_NUM * 4); 17149a2135eSLin Jinhan } 17249a2135eSLin Jinhan 173c3ce9937SLin Jinhan static inline void read_regs(u32 base, u8 *data, u32 data_len) 174c3ce9937SLin Jinhan { 175c3ce9937SLin Jinhan u8 tmp_buf[4]; 176c3ce9937SLin Jinhan u32 i; 177c3ce9937SLin Jinhan 178c3ce9937SLin Jinhan for (i = 0; i < data_len / 4; i++) 179c3ce9937SLin Jinhan word2byte_be(crypto_read(base + i * 4), 180c3ce9937SLin Jinhan data + i * 4); 181c3ce9937SLin Jinhan 182c3ce9937SLin Jinhan if (data_len % 4) { 183c3ce9937SLin Jinhan word2byte_be(crypto_read(base + i * 4), tmp_buf); 184c3ce9937SLin Jinhan memcpy(data + i * 4, tmp_buf, data_len % 4); 185c3ce9937SLin Jinhan } 186c3ce9937SLin Jinhan } 187c3ce9937SLin Jinhan 18849a2135eSLin Jinhan static inline void write_regs(u32 base, const u8 *data, u32 data_len) 18949a2135eSLin Jinhan { 19049a2135eSLin Jinhan u8 tmp_buf[4]; 19149a2135eSLin Jinhan u32 i; 19249a2135eSLin Jinhan 19349a2135eSLin Jinhan for (i = 0; i < data_len / 4; i++, base += 4) 19449a2135eSLin Jinhan crypto_write(byte2word_be(data + i * 4), base); 19549a2135eSLin Jinhan 19649a2135eSLin Jinhan if (data_len % 4) { 19749a2135eSLin Jinhan memset(tmp_buf, 0x00, sizeof(tmp_buf)); 19849a2135eSLin Jinhan memcpy((u8 *)tmp_buf, data + i * 4, data_len % 4); 19949a2135eSLin Jinhan crypto_write(byte2word_be(tmp_buf), base); 20049a2135eSLin Jinhan } 20149a2135eSLin Jinhan } 20249a2135eSLin Jinhan 20349a2135eSLin Jinhan static inline void write_key_reg(u32 chn, const u8 *key, u32 key_len) 20449a2135eSLin Jinhan { 20549a2135eSLin Jinhan write_regs(CRYPTO_CH0_KEY_0 + chn * 0x10, key, key_len); 20649a2135eSLin Jinhan } 20749a2135eSLin Jinhan 20849a2135eSLin Jinhan static inline void set_iv_reg(u32 chn, const u8 *iv, u32 iv_len) 20949a2135eSLin Jinhan { 21049a2135eSLin Jinhan u32 base_iv; 21149a2135eSLin Jinhan 21249a2135eSLin Jinhan base_iv = CRYPTO_CH0_IV_0 + chn * 0x10; 21349a2135eSLin Jinhan 21449a2135eSLin Jinhan /* clear iv */ 21549a2135eSLin Jinhan clear_regs(base_iv, 4); 21649a2135eSLin Jinhan 21749a2135eSLin Jinhan if (!iv || iv_len == 0) 21849a2135eSLin Jinhan return; 21949a2135eSLin Jinhan 22049a2135eSLin Jinhan write_regs(base_iv, iv, iv_len); 22149a2135eSLin Jinhan 22249a2135eSLin Jinhan crypto_write(iv_len, CRYPTO_CH0_IV_LEN_0 + 4 * chn); 223b353a43cSLin Jinhan } 224b353a43cSLin Jinhan 225c3ce9937SLin Jinhan static inline void get_iv_reg(u32 chn, u8 *iv, u32 iv_len) 226c3ce9937SLin Jinhan { 227c3ce9937SLin Jinhan u32 base_iv; 228c3ce9937SLin Jinhan 229c3ce9937SLin Jinhan base_iv = CRYPTO_CH0_IV_0 + chn * 0x10; 230c3ce9937SLin Jinhan 231c3ce9937SLin Jinhan read_regs(base_iv, iv, iv_len); 232c3ce9937SLin Jinhan } 233c3ce9937SLin Jinhan 234d9332f1cSLin Jinhan static inline void get_tag_from_reg(u32 chn, u8 *tag, u32 tag_len) 235d9332f1cSLin Jinhan { 236d9332f1cSLin Jinhan u32 i; 237d9332f1cSLin Jinhan u32 chn_base = CRYPTO_CH0_TAG_0 + 0x10 * chn; 238d9332f1cSLin Jinhan 239d9332f1cSLin Jinhan for (i = 0; i < tag_len / 4; i++, chn_base += 4) 240d9332f1cSLin Jinhan word2byte_be(crypto_read(chn_base), tag + 4 * i); 241d9332f1cSLin Jinhan } 242d9332f1cSLin Jinhan 243dd7763a8SFinley Xiao static int rk_crypto_do_enable_clk(struct udevice *dev, int enable) 244dd7763a8SFinley Xiao { 245dd7763a8SFinley Xiao struct rockchip_crypto_priv *priv = dev_get_priv(dev); 246dd7763a8SFinley Xiao struct clk clk; 247dd7763a8SFinley Xiao int i, ret; 248dd7763a8SFinley Xiao 249dd7763a8SFinley Xiao for (i = 0; i < priv->nclocks; i++) { 250dd7763a8SFinley Xiao ret = clk_get_by_index(dev, i, &clk); 251dd7763a8SFinley Xiao if (ret < 0) { 252dd7763a8SFinley Xiao printf("Failed to get clk index %d, ret=%d\n", i, ret); 253dd7763a8SFinley Xiao return ret; 254dd7763a8SFinley Xiao } 255dd7763a8SFinley Xiao 256dd7763a8SFinley Xiao if (enable) 257dd7763a8SFinley Xiao ret = clk_enable(&clk); 258dd7763a8SFinley Xiao else 259dd7763a8SFinley Xiao ret = clk_disable(&clk); 260dd7763a8SFinley Xiao if (ret < 0 && ret != -ENOSYS) { 261dd7763a8SFinley Xiao printf("Failed to enable(%d) clk(%ld): ret=%d\n", 262dd7763a8SFinley Xiao enable, clk.id, ret); 263dd7763a8SFinley Xiao return ret; 264dd7763a8SFinley Xiao } 265dd7763a8SFinley Xiao } 266dd7763a8SFinley Xiao 267dd7763a8SFinley Xiao return 0; 268dd7763a8SFinley Xiao } 269dd7763a8SFinley Xiao 270dd7763a8SFinley Xiao static int rk_crypto_enable_clk(struct udevice *dev) 271dd7763a8SFinley Xiao { 272dd7763a8SFinley Xiao return rk_crypto_do_enable_clk(dev, 1); 273dd7763a8SFinley Xiao } 274dd7763a8SFinley Xiao 275dd7763a8SFinley Xiao static int rk_crypto_disable_clk(struct udevice *dev) 276dd7763a8SFinley Xiao { 277dd7763a8SFinley Xiao return rk_crypto_do_enable_clk(dev, 0); 278dd7763a8SFinley Xiao } 279dd7763a8SFinley Xiao 28058432b6fSLin Jinhan static u32 crypto_v3_dynamic_cap(void) 28158432b6fSLin Jinhan { 28258432b6fSLin Jinhan u32 capability = 0; 28358432b6fSLin Jinhan u32 ver_reg, i; 28458432b6fSLin Jinhan struct cap_map { 28558432b6fSLin Jinhan u32 ver_offset; 28658432b6fSLin Jinhan u32 mask; 28758432b6fSLin Jinhan u32 cap_bit; 28858432b6fSLin Jinhan }; 28958432b6fSLin Jinhan const struct cap_map cap_tbl[] = { 29058432b6fSLin Jinhan {CRYPTO_HASH_VERSION, CRYPTO_HASH_MD5_FLAG, CRYPTO_MD5}, 29158432b6fSLin Jinhan {CRYPTO_HASH_VERSION, CRYPTO_HASH_SHA1_FLAG, CRYPTO_SHA1}, 29258432b6fSLin Jinhan {CRYPTO_HASH_VERSION, CRYPTO_HASH_SHA256_FLAG, CRYPTO_SHA256}, 29358432b6fSLin Jinhan {CRYPTO_HASH_VERSION, CRYPTO_HASH_SHA512_FLAG, CRYPTO_SHA512}, 29458432b6fSLin Jinhan {CRYPTO_HASH_VERSION, CRYPTO_HASH_SM3_FLAG, CRYPTO_SM3}, 29558432b6fSLin Jinhan 29658432b6fSLin Jinhan {CRYPTO_HMAC_VERSION, CRYPTO_HMAC_MD5_FLAG, CRYPTO_HMAC_MD5}, 29758432b6fSLin Jinhan {CRYPTO_HMAC_VERSION, CRYPTO_HMAC_SHA1_FLAG, CRYPTO_HMAC_SHA1}, 29858432b6fSLin Jinhan {CRYPTO_HMAC_VERSION, CRYPTO_HMAC_SHA256_FLAG, CRYPTO_HMAC_SHA256}, 29958432b6fSLin Jinhan {CRYPTO_HMAC_VERSION, CRYPTO_HMAC_SHA512_FLAG, CRYPTO_HMAC_SHA512}, 30058432b6fSLin Jinhan {CRYPTO_HMAC_VERSION, CRYPTO_HMAC_SM3_FLAG, CRYPTO_HMAC_SM3}, 30158432b6fSLin Jinhan 30258432b6fSLin Jinhan {CRYPTO_AES_VERSION, CRYPTO_AES256_FLAG, CRYPTO_AES}, 30358432b6fSLin Jinhan {CRYPTO_DES_VERSION, CRYPTO_TDES_FLAG, CRYPTO_DES}, 30458432b6fSLin Jinhan {CRYPTO_SM4_VERSION, CRYPTO_ECB_FLAG, CRYPTO_SM4}, 30558432b6fSLin Jinhan }; 30658432b6fSLin Jinhan 30758432b6fSLin Jinhan /* rsa */ 30858432b6fSLin Jinhan capability = CRYPTO_RSA512 | 30958432b6fSLin Jinhan CRYPTO_RSA1024 | 31058432b6fSLin Jinhan CRYPTO_RSA2048 | 31158432b6fSLin Jinhan CRYPTO_RSA3072 | 31258432b6fSLin Jinhan CRYPTO_RSA4096; 31358432b6fSLin Jinhan 31402b4cf42SLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_EC) 31502b4cf42SLin Jinhan capability |= (CRYPTO_SM2 | 31602b4cf42SLin Jinhan CRYPTO_ECC_192R1 | 31702b4cf42SLin Jinhan CRYPTO_ECC_224R1 | 31802b4cf42SLin Jinhan CRYPTO_ECC_256R1); 31902b4cf42SLin Jinhan #endif 32002b4cf42SLin Jinhan 32158432b6fSLin Jinhan for (i = 0; i < ARRAY_SIZE(cap_tbl); i++) { 32258432b6fSLin Jinhan ver_reg = crypto_read(cap_tbl[i].ver_offset); 32358432b6fSLin Jinhan 32458432b6fSLin Jinhan if ((ver_reg & cap_tbl[i].mask) == cap_tbl[i].mask) 32558432b6fSLin Jinhan capability |= cap_tbl[i].cap_bit; 32658432b6fSLin Jinhan } 32758432b6fSLin Jinhan 32858432b6fSLin Jinhan return capability; 32958432b6fSLin Jinhan } 33058432b6fSLin Jinhan 331b353a43cSLin Jinhan static int hw_crypto_reset(void) 332b353a43cSLin Jinhan { 33349a2135eSLin Jinhan u32 val = 0, mask = 0; 334b353a43cSLin Jinhan int ret; 335b353a43cSLin Jinhan 33649a2135eSLin Jinhan val = CRYPTO_SW_PKA_RESET | CRYPTO_SW_CC_RESET; 33749a2135eSLin Jinhan mask = val << CRYPTO_WRITE_MASK_SHIFT; 338b353a43cSLin Jinhan 339b353a43cSLin Jinhan /* reset pka and crypto modules*/ 34049a2135eSLin Jinhan crypto_write(val | mask, CRYPTO_RST_CTL); 341b353a43cSLin Jinhan 342b353a43cSLin Jinhan /* wait reset compelete */ 34349a2135eSLin Jinhan ret = RK_POLL_TIMEOUT(crypto_read(CRYPTO_RST_CTL), RK_CRYPTO_TIMEOUT); 34449a2135eSLin Jinhan 345e0c259feSLin Jinhan g_crypto_version = crypto_read(CRYPTO_CRYPTO_VERSION_NEW); 346e0c259feSLin Jinhan 347b353a43cSLin Jinhan return ret; 348b353a43cSLin Jinhan } 349b353a43cSLin Jinhan 350b353a43cSLin Jinhan static void hw_hash_clean_ctx(struct rk_hash_ctx *ctx) 351b353a43cSLin Jinhan { 352b353a43cSLin Jinhan /* clear hash status */ 353b353a43cSLin Jinhan crypto_write(CRYPTO_WRITE_MASK_ALL | 0, CRYPTO_HASH_CTL); 354b353a43cSLin Jinhan 3551606a214SLin Jinhan assert(ctx); 3561606a214SLin Jinhan assert(ctx->magic == RK_HASH_CTX_MAGIC); 3571606a214SLin Jinhan 358c48f1acfSLin Jinhan crypto_hash_cache_free(ctx->hash_cache); 3591606a214SLin Jinhan 3601606a214SLin Jinhan memset(ctx, 0x00, sizeof(*ctx)); 361b353a43cSLin Jinhan } 362b353a43cSLin Jinhan 363c48f1acfSLin Jinhan static int rk_hash_init(void *hw_ctx, u32 algo) 364b353a43cSLin Jinhan { 365b353a43cSLin Jinhan struct rk_hash_ctx *tmp_ctx = (struct rk_hash_ctx *)hw_ctx; 366b353a43cSLin Jinhan u32 reg_ctrl = 0; 367b353a43cSLin Jinhan int ret; 368b353a43cSLin Jinhan 369b353a43cSLin Jinhan if (!tmp_ctx) 370b353a43cSLin Jinhan return -EINVAL; 371b353a43cSLin Jinhan 3721606a214SLin Jinhan reg_ctrl = CRYPTO_SW_CC_RESET; 3731606a214SLin Jinhan crypto_write(reg_ctrl | (reg_ctrl << CRYPTO_WRITE_MASK_SHIFT), 3741606a214SLin Jinhan CRYPTO_RST_CTL); 3751606a214SLin Jinhan 3761606a214SLin Jinhan /* wait reset compelete */ 37749a2135eSLin Jinhan ret = RK_POLL_TIMEOUT(crypto_read(CRYPTO_RST_CTL), 37849a2135eSLin Jinhan RK_CRYPTO_TIMEOUT); 3791606a214SLin Jinhan 3801606a214SLin Jinhan reg_ctrl = 0; 381b353a43cSLin Jinhan tmp_ctx->algo = algo; 382b353a43cSLin Jinhan switch (algo) { 383b353a43cSLin Jinhan case CRYPTO_MD5: 38449a2135eSLin Jinhan case CRYPTO_HMAC_MD5: 385b353a43cSLin Jinhan reg_ctrl |= CRYPTO_MODE_MD5; 386b353a43cSLin Jinhan tmp_ctx->digest_size = 16; 387b353a43cSLin Jinhan break; 388b353a43cSLin Jinhan case CRYPTO_SHA1: 38949a2135eSLin Jinhan case CRYPTO_HMAC_SHA1: 390b353a43cSLin Jinhan reg_ctrl |= CRYPTO_MODE_SHA1; 391b353a43cSLin Jinhan tmp_ctx->digest_size = 20; 392b353a43cSLin Jinhan break; 393b353a43cSLin Jinhan case CRYPTO_SHA256: 39449a2135eSLin Jinhan case CRYPTO_HMAC_SHA256: 395b353a43cSLin Jinhan reg_ctrl |= CRYPTO_MODE_SHA256; 396b353a43cSLin Jinhan tmp_ctx->digest_size = 32; 397b353a43cSLin Jinhan break; 398e7846385SLin Jinhan case CRYPTO_SHA512: 39949a2135eSLin Jinhan case CRYPTO_HMAC_SHA512: 400e7846385SLin Jinhan reg_ctrl |= CRYPTO_MODE_SHA512; 401e7846385SLin Jinhan tmp_ctx->digest_size = 64; 402e7846385SLin Jinhan break; 40349a2135eSLin Jinhan case CRYPTO_SM3: 40449a2135eSLin Jinhan case CRYPTO_HMAC_SM3: 40549a2135eSLin Jinhan reg_ctrl |= CRYPTO_MODE_SM3; 40649a2135eSLin Jinhan tmp_ctx->digest_size = 32; 40749a2135eSLin Jinhan break; 408b353a43cSLin Jinhan default: 409b353a43cSLin Jinhan ret = -EINVAL; 410b353a43cSLin Jinhan goto exit; 411b353a43cSLin Jinhan } 412b353a43cSLin Jinhan 413b353a43cSLin Jinhan /* enable hardware padding */ 414b353a43cSLin Jinhan reg_ctrl |= CRYPTO_HW_PAD_ENABLE; 415b353a43cSLin Jinhan crypto_write(reg_ctrl | CRYPTO_WRITE_MASK_ALL, CRYPTO_HASH_CTL); 416b353a43cSLin Jinhan 417b353a43cSLin Jinhan /* FIFO input and output data byte swap */ 418b353a43cSLin Jinhan /* such as B0, B1, B2, B3 -> B3, B2, B1, B0 */ 419b353a43cSLin Jinhan reg_ctrl = CRYPTO_DOUT_BYTESWAP | CRYPTO_DOIN_BYTESWAP; 420b353a43cSLin Jinhan crypto_write(reg_ctrl | CRYPTO_WRITE_MASK_ALL, CRYPTO_FIFO_CTL); 421b353a43cSLin Jinhan 4221606a214SLin Jinhan /* enable src_item_done interrupt */ 423fe0c4b19SLin Jinhan crypto_write(0, CRYPTO_DMA_INT_EN); 424b353a43cSLin Jinhan 425b353a43cSLin Jinhan tmp_ctx->magic = RK_HASH_CTX_MAGIC; 426b353a43cSLin Jinhan 427b353a43cSLin Jinhan return 0; 428b353a43cSLin Jinhan exit: 429b353a43cSLin Jinhan /* clear hash setting if init failed */ 430b353a43cSLin Jinhan crypto_write(CRYPTO_WRITE_MASK_ALL | 0, CRYPTO_HASH_CTL); 431b353a43cSLin Jinhan 432b353a43cSLin Jinhan return ret; 433b353a43cSLin Jinhan } 434b353a43cSLin Jinhan 435c48f1acfSLin Jinhan static int rk_hash_direct_calc(void *hw_data, const u8 *data, 4361606a214SLin Jinhan u32 data_len, u8 *started_flag, u8 is_last) 437b353a43cSLin Jinhan { 438c48f1acfSLin Jinhan struct rockchip_crypto_priv *priv = hw_data; 439c48f1acfSLin Jinhan struct rk_hash_ctx *hash_ctx = priv->hw_ctx; 440c48f1acfSLin Jinhan struct crypto_lli_desc *lli = &hash_ctx->data_lli; 441b353a43cSLin Jinhan int ret = -EINVAL; 44200fa57d8SLin Jinhan u32 tmp = 0, mask = 0; 443b353a43cSLin Jinhan 44449a2135eSLin Jinhan assert(IS_ALIGNED((ulong)data, DATA_ADDR_ALIGN_SIZE)); 44549a2135eSLin Jinhan assert(is_last || IS_ALIGNED(data_len, DATA_LEN_ALIGN_SIZE)); 446b353a43cSLin Jinhan 4471606a214SLin Jinhan debug("%s: data = %p, len = %u, s = %x, l = %x\n", 4481606a214SLin Jinhan __func__, data, data_len, *started_flag, is_last); 449b353a43cSLin Jinhan 4501606a214SLin Jinhan memset(lli, 0x00, sizeof(*lli)); 4511606a214SLin Jinhan lli->src_addr = (u32)virt_to_phys(data); 4521606a214SLin Jinhan lli->src_len = data_len; 4531606a214SLin Jinhan lli->dma_ctrl = LLI_DMA_CTRL_SRC_DONE; 454b353a43cSLin Jinhan 4551606a214SLin Jinhan if (is_last) { 4561606a214SLin Jinhan lli->user_define |= LLI_USER_STRING_LAST; 4571606a214SLin Jinhan lli->dma_ctrl |= LLI_DMA_CTRL_LAST; 458b353a43cSLin Jinhan } else { 4591606a214SLin Jinhan lli->next_addr = (u32)virt_to_phys(lli); 4601606a214SLin Jinhan lli->dma_ctrl |= LLI_DMA_CTRL_PAUSE; 4611606a214SLin Jinhan } 4621606a214SLin Jinhan 4631606a214SLin Jinhan if (!(*started_flag)) { 4641606a214SLin Jinhan lli->user_define |= 465ce7f4cd6SLin Jinhan (LLI_USER_STRING_START | LLI_USER_CIPHER_START); 4661606a214SLin Jinhan crypto_write((u32)virt_to_phys(lli), CRYPTO_DMA_LLI_ADDR); 4671606a214SLin Jinhan crypto_write((CRYPTO_HASH_ENABLE << CRYPTO_WRITE_MASK_SHIFT) | 4681606a214SLin Jinhan CRYPTO_HASH_ENABLE, CRYPTO_HASH_CTL); 4691606a214SLin Jinhan tmp = CRYPTO_DMA_START; 4701606a214SLin Jinhan *started_flag = 1; 4711606a214SLin Jinhan } else { 472b353a43cSLin Jinhan tmp = CRYPTO_DMA_RESTART; 473b353a43cSLin Jinhan } 474b353a43cSLin Jinhan 475b353a43cSLin Jinhan /* flush cache */ 476c48f1acfSLin Jinhan crypto_flush_cacheline((ulong)lli, sizeof(*lli)); 477c48f1acfSLin Jinhan crypto_flush_cacheline((ulong)data, data_len); 478b353a43cSLin Jinhan 479b353a43cSLin Jinhan /* start calculate */ 480b353a43cSLin Jinhan crypto_write(tmp << CRYPTO_WRITE_MASK_SHIFT | tmp, 481b353a43cSLin Jinhan CRYPTO_DMA_CTL); 482b353a43cSLin Jinhan 48300fa57d8SLin Jinhan /* mask CRYPTO_SYNC_LOCKSTEP_INT_ST flag */ 48400fa57d8SLin Jinhan mask = ~(mask | CRYPTO_SYNC_LOCKSTEP_INT_ST); 48500fa57d8SLin Jinhan 486b353a43cSLin Jinhan /* wait calc ok */ 48749a2135eSLin Jinhan ret = RK_POLL_TIMEOUT(!(crypto_read(CRYPTO_DMA_INT_ST) & mask), 48849a2135eSLin Jinhan RK_CRYPTO_TIMEOUT); 489b353a43cSLin Jinhan 490b353a43cSLin Jinhan /* clear interrupt status */ 491b353a43cSLin Jinhan tmp = crypto_read(CRYPTO_DMA_INT_ST); 492b353a43cSLin Jinhan crypto_write(tmp, CRYPTO_DMA_INT_ST); 493b353a43cSLin Jinhan 49449cbb0faSLin Jinhan if ((tmp & mask) != CRYPTO_SRC_ITEM_DONE_INT_ST && 49549cbb0faSLin Jinhan (tmp & mask) != CRYPTO_ZERO_LEN_INT_ST) { 49646aac970SLin Jinhan ret = -EFAULT; 4971606a214SLin Jinhan debug("[%s] %d: CRYPTO_DMA_INT_ST = 0x%x\n", 498b353a43cSLin Jinhan __func__, __LINE__, tmp); 4991606a214SLin Jinhan goto exit; 500b353a43cSLin Jinhan } 501b353a43cSLin Jinhan 502c48f1acfSLin Jinhan priv->length += data_len; 5031606a214SLin Jinhan exit: 5041606a214SLin Jinhan return ret; 505b353a43cSLin Jinhan } 5061606a214SLin Jinhan 5071606a214SLin Jinhan int rk_hash_update(void *ctx, const u8 *data, u32 data_len) 5081606a214SLin Jinhan { 5091606a214SLin Jinhan struct rk_hash_ctx *tmp_ctx = (struct rk_hash_ctx *)ctx; 510c48f1acfSLin Jinhan int ret = -EINVAL; 5111606a214SLin Jinhan 5121606a214SLin Jinhan debug("\n"); 5131606a214SLin Jinhan if (!tmp_ctx || !data) 514c48f1acfSLin Jinhan goto exit; 5151606a214SLin Jinhan 5161606a214SLin Jinhan if (tmp_ctx->digest_size == 0 || tmp_ctx->magic != RK_HASH_CTX_MAGIC) 517c48f1acfSLin Jinhan goto exit; 5181606a214SLin Jinhan 519c48f1acfSLin Jinhan ret = crypto_hash_update_with_cache(tmp_ctx->hash_cache, 520c48f1acfSLin Jinhan data, data_len); 5211606a214SLin Jinhan 522c48f1acfSLin Jinhan exit: 523b353a43cSLin Jinhan /* free lli list */ 524c48f1acfSLin Jinhan if (ret) 525b353a43cSLin Jinhan hw_hash_clean_ctx(tmp_ctx); 526b353a43cSLin Jinhan 527c48f1acfSLin Jinhan return ret; 528b353a43cSLin Jinhan } 529b353a43cSLin Jinhan 530b353a43cSLin Jinhan int rk_hash_final(void *ctx, u8 *digest, size_t len) 531b353a43cSLin Jinhan { 532b353a43cSLin Jinhan struct rk_hash_ctx *tmp_ctx = (struct rk_hash_ctx *)ctx; 533e0c259feSLin Jinhan int ret = 0; 534b353a43cSLin Jinhan 535b353a43cSLin Jinhan if (!digest) 536b353a43cSLin Jinhan goto exit; 537b353a43cSLin Jinhan 538b353a43cSLin Jinhan if (!tmp_ctx || 539b353a43cSLin Jinhan tmp_ctx->digest_size == 0 || 540b353a43cSLin Jinhan len > tmp_ctx->digest_size || 541b353a43cSLin Jinhan tmp_ctx->magic != RK_HASH_CTX_MAGIC) { 542b353a43cSLin Jinhan goto exit; 543b353a43cSLin Jinhan } 544b353a43cSLin Jinhan 545e0c259feSLin Jinhan if(is_check_hash_valid()) { 546b353a43cSLin Jinhan /* wait hash value ok */ 54749a2135eSLin Jinhan ret = RK_POLL_TIMEOUT(!crypto_read(CRYPTO_HASH_VALID), 54849a2135eSLin Jinhan RK_CRYPTO_TIMEOUT); 549e0c259feSLin Jinhan } 550b353a43cSLin Jinhan 551c3ce9937SLin Jinhan read_regs(CRYPTO_HASH_DOUT_0, digest, len); 552b353a43cSLin Jinhan 553b353a43cSLin Jinhan /* clear hash status */ 554b353a43cSLin Jinhan crypto_write(CRYPTO_HASH_IS_VALID, CRYPTO_HASH_VALID); 555b353a43cSLin Jinhan crypto_write(CRYPTO_WRITE_MASK_ALL | 0, CRYPTO_HASH_CTL); 556b353a43cSLin Jinhan 557b353a43cSLin Jinhan exit: 558b353a43cSLin Jinhan 559b353a43cSLin Jinhan return ret; 560b353a43cSLin Jinhan } 561b353a43cSLin Jinhan 562b353a43cSLin Jinhan static u32 rockchip_crypto_capability(struct udevice *dev) 563b353a43cSLin Jinhan { 56449a2135eSLin Jinhan struct rockchip_crypto_priv *priv = dev_get_priv(dev); 56549a2135eSLin Jinhan u32 capability, mask = 0; 5667eea1823SLin Jinhan 56749a2135eSLin Jinhan capability = priv->soc_data->capability; 56849a2135eSLin Jinhan 56949a2135eSLin Jinhan #if !(CONFIG_IS_ENABLED(ROCKCHIP_CIPHER)) 57049a2135eSLin Jinhan mask |= (CRYPTO_DES | CRYPTO_AES | CRYPTO_SM4); 571c0e47d03SLin Jinhan #endif 5727eea1823SLin Jinhan 57349a2135eSLin Jinhan #if !(CONFIG_IS_ENABLED(ROCKCHIP_HMAC)) 57449a2135eSLin Jinhan mask |= (CRYPTO_HMAC_MD5 | CRYPTO_HMAC_SHA1 | CRYPTO_HMAC_SHA256 | 57549a2135eSLin Jinhan CRYPTO_HMAC_SHA512 | CRYPTO_HMAC_SM3); 57649a2135eSLin Jinhan #endif 57749a2135eSLin Jinhan 57849a2135eSLin Jinhan #if !(CONFIG_IS_ENABLED(ROCKCHIP_RSA)) 57949a2135eSLin Jinhan mask |= (CRYPTO_RSA512 | CRYPTO_RSA1024 | CRYPTO_RSA2048 | 58049a2135eSLin Jinhan CRYPTO_RSA3072 | CRYPTO_RSA4096); 58149a2135eSLin Jinhan #endif 58249a2135eSLin Jinhan 58349a2135eSLin Jinhan return capability & (~mask); 584b353a43cSLin Jinhan } 585b353a43cSLin Jinhan 586b353a43cSLin Jinhan static int rockchip_crypto_sha_init(struct udevice *dev, sha_context *ctx) 587b353a43cSLin Jinhan { 588b353a43cSLin Jinhan struct rockchip_crypto_priv *priv = dev_get_priv(dev); 589c48f1acfSLin Jinhan struct rk_hash_ctx *hash_ctx = priv->hw_ctx; 590dd7763a8SFinley Xiao int ret = 0; 591b353a43cSLin Jinhan 592b353a43cSLin Jinhan if (!ctx) 593b353a43cSLin Jinhan return -EINVAL; 594b353a43cSLin Jinhan 595c48f1acfSLin Jinhan memset(hash_ctx, 0x00, sizeof(*hash_ctx)); 596b353a43cSLin Jinhan 597c48f1acfSLin Jinhan priv->length = 0; 598c48f1acfSLin Jinhan 599c48f1acfSLin Jinhan hash_ctx->hash_cache = crypto_hash_cache_alloc(rk_hash_direct_calc, 600c48f1acfSLin Jinhan priv, ctx->length, 60149a2135eSLin Jinhan DATA_ADDR_ALIGN_SIZE, 60249a2135eSLin Jinhan DATA_LEN_ALIGN_SIZE); 603c48f1acfSLin Jinhan if (!hash_ctx->hash_cache) 604c48f1acfSLin Jinhan return -EFAULT; 605c48f1acfSLin Jinhan 606dd7763a8SFinley Xiao rk_crypto_enable_clk(dev); 607dd7763a8SFinley Xiao ret = rk_hash_init(hash_ctx, ctx->algo); 608dd7763a8SFinley Xiao if (ret) 609dd7763a8SFinley Xiao rk_crypto_disable_clk(dev); 610dd7763a8SFinley Xiao 611dd7763a8SFinley Xiao return ret; 612b353a43cSLin Jinhan } 613b353a43cSLin Jinhan 614b353a43cSLin Jinhan static int rockchip_crypto_sha_update(struct udevice *dev, 615b353a43cSLin Jinhan u32 *input, u32 len) 616b353a43cSLin Jinhan { 617b353a43cSLin Jinhan struct rockchip_crypto_priv *priv = dev_get_priv(dev); 618086e8fa8SLin Jinhan int ret, i; 619086e8fa8SLin Jinhan u8 *p; 620b353a43cSLin Jinhan 621dd7763a8SFinley Xiao if (!len) { 622dd7763a8SFinley Xiao ret = -EINVAL; 623dd7763a8SFinley Xiao goto exit; 624dd7763a8SFinley Xiao } 625b353a43cSLin Jinhan 626086e8fa8SLin Jinhan p = (u8 *)input; 627086e8fa8SLin Jinhan 628086e8fa8SLin Jinhan for (i = 0; i < len / HASH_UPDATE_LIMIT; i++, p += HASH_UPDATE_LIMIT) { 629086e8fa8SLin Jinhan ret = rk_hash_update(priv->hw_ctx, p, HASH_UPDATE_LIMIT); 630086e8fa8SLin Jinhan if (ret) 631086e8fa8SLin Jinhan goto exit; 632086e8fa8SLin Jinhan } 633086e8fa8SLin Jinhan 634086e8fa8SLin Jinhan if (len % HASH_UPDATE_LIMIT) 635086e8fa8SLin Jinhan ret = rk_hash_update(priv->hw_ctx, p, len % HASH_UPDATE_LIMIT); 636086e8fa8SLin Jinhan 637086e8fa8SLin Jinhan exit: 638dd7763a8SFinley Xiao if (ret) 639dd7763a8SFinley Xiao rk_crypto_disable_clk(dev); 640dd7763a8SFinley Xiao 641086e8fa8SLin Jinhan return ret; 642b353a43cSLin Jinhan } 643b353a43cSLin Jinhan 644b353a43cSLin Jinhan static int rockchip_crypto_sha_final(struct udevice *dev, 645b353a43cSLin Jinhan sha_context *ctx, u8 *output) 646b353a43cSLin Jinhan { 647b353a43cSLin Jinhan struct rockchip_crypto_priv *priv = dev_get_priv(dev); 648b353a43cSLin Jinhan u32 nbits; 649c48f1acfSLin Jinhan int ret; 650b353a43cSLin Jinhan 651b353a43cSLin Jinhan nbits = crypto_algo_nbits(ctx->algo); 652b353a43cSLin Jinhan 653c48f1acfSLin Jinhan if (priv->length != ctx->length) { 654c48f1acfSLin Jinhan printf("total length(0x%08x) != init length(0x%08x)!\n", 655c48f1acfSLin Jinhan priv->length, ctx->length); 656c48f1acfSLin Jinhan ret = -EIO; 657c48f1acfSLin Jinhan goto exit; 658c48f1acfSLin Jinhan } 659c48f1acfSLin Jinhan 660c48f1acfSLin Jinhan ret = rk_hash_final(priv->hw_ctx, (u8 *)output, BITS2BYTE(nbits)); 661c48f1acfSLin Jinhan 662c48f1acfSLin Jinhan exit: 663c48f1acfSLin Jinhan hw_hash_clean_ctx(priv->hw_ctx); 664dd7763a8SFinley Xiao rk_crypto_disable_clk(dev); 665dd7763a8SFinley Xiao 666c48f1acfSLin Jinhan return ret; 667b353a43cSLin Jinhan } 668b353a43cSLin Jinhan 66949a2135eSLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_HMAC) 67049a2135eSLin Jinhan int rk_hmac_init(void *hw_ctx, u32 algo, u8 *key, u32 key_len) 67149a2135eSLin Jinhan { 67249a2135eSLin Jinhan u32 reg_ctrl = 0; 67349a2135eSLin Jinhan int ret; 67449a2135eSLin Jinhan 67549a2135eSLin Jinhan if (!key || !key_len || key_len > 64) 67649a2135eSLin Jinhan return -EINVAL; 67749a2135eSLin Jinhan 67849a2135eSLin Jinhan clear_key_regs(); 67949a2135eSLin Jinhan 68049a2135eSLin Jinhan write_key_reg(0, key, key_len); 68149a2135eSLin Jinhan 68249a2135eSLin Jinhan ret = rk_hash_init(hw_ctx, algo); 68349a2135eSLin Jinhan if (ret) 68449a2135eSLin Jinhan return ret; 68549a2135eSLin Jinhan 68649a2135eSLin Jinhan reg_ctrl = crypto_read(CRYPTO_HASH_CTL) | CRYPTO_HMAC_ENABLE; 68749a2135eSLin Jinhan crypto_write(reg_ctrl | CRYPTO_WRITE_MASK_ALL, CRYPTO_HASH_CTL); 68849a2135eSLin Jinhan 68949a2135eSLin Jinhan return ret; 69049a2135eSLin Jinhan } 69149a2135eSLin Jinhan 69249a2135eSLin Jinhan static int rockchip_crypto_hmac_init(struct udevice *dev, 69349a2135eSLin Jinhan sha_context *ctx, u8 *key, u32 key_len) 69449a2135eSLin Jinhan { 69549a2135eSLin Jinhan struct rockchip_crypto_priv *priv = dev_get_priv(dev); 69649a2135eSLin Jinhan struct rk_hash_ctx *hash_ctx = priv->hw_ctx; 697dd7763a8SFinley Xiao int ret = 0; 69849a2135eSLin Jinhan 69949a2135eSLin Jinhan if (!ctx) 70049a2135eSLin Jinhan return -EINVAL; 70149a2135eSLin Jinhan 70249a2135eSLin Jinhan memset(hash_ctx, 0x00, sizeof(*hash_ctx)); 70349a2135eSLin Jinhan 70449a2135eSLin Jinhan priv->length = 0; 70549a2135eSLin Jinhan 70649a2135eSLin Jinhan hash_ctx->hash_cache = crypto_hash_cache_alloc(rk_hash_direct_calc, 70749a2135eSLin Jinhan priv, ctx->length, 70849a2135eSLin Jinhan DATA_ADDR_ALIGN_SIZE, 70949a2135eSLin Jinhan DATA_LEN_ALIGN_SIZE); 71049a2135eSLin Jinhan if (!hash_ctx->hash_cache) 71149a2135eSLin Jinhan return -EFAULT; 71249a2135eSLin Jinhan 713dd7763a8SFinley Xiao rk_crypto_enable_clk(dev); 714dd7763a8SFinley Xiao ret = rk_hmac_init(priv->hw_ctx, ctx->algo, key, key_len); 715dd7763a8SFinley Xiao if (ret) 716dd7763a8SFinley Xiao rk_crypto_disable_clk(dev); 717dd7763a8SFinley Xiao 718dd7763a8SFinley Xiao return ret; 71949a2135eSLin Jinhan } 72049a2135eSLin Jinhan 72149a2135eSLin Jinhan static int rockchip_crypto_hmac_update(struct udevice *dev, 72249a2135eSLin Jinhan u32 *input, u32 len) 72349a2135eSLin Jinhan { 72449a2135eSLin Jinhan return rockchip_crypto_sha_update(dev, input, len); 72549a2135eSLin Jinhan } 72649a2135eSLin Jinhan 72749a2135eSLin Jinhan static int rockchip_crypto_hmac_final(struct udevice *dev, 72849a2135eSLin Jinhan sha_context *ctx, u8 *output) 72949a2135eSLin Jinhan { 73049a2135eSLin Jinhan return rockchip_crypto_sha_final(dev, ctx, output); 73149a2135eSLin Jinhan } 73249a2135eSLin Jinhan 73349a2135eSLin Jinhan #endif 73449a2135eSLin Jinhan 73549a2135eSLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_CIPHER) 73649a2135eSLin Jinhan static u8 g_key_chn; 73749a2135eSLin Jinhan 73849a2135eSLin Jinhan static const u32 rk_mode2bc_mode[RK_MODE_MAX] = { 73949a2135eSLin Jinhan [RK_MODE_ECB] = CRYPTO_BC_ECB, 74049a2135eSLin Jinhan [RK_MODE_CBC] = CRYPTO_BC_CBC, 74149a2135eSLin Jinhan [RK_MODE_CTS] = CRYPTO_BC_CTS, 74249a2135eSLin Jinhan [RK_MODE_CTR] = CRYPTO_BC_CTR, 74349a2135eSLin Jinhan [RK_MODE_CFB] = CRYPTO_BC_CFB, 74449a2135eSLin Jinhan [RK_MODE_OFB] = CRYPTO_BC_OFB, 74549a2135eSLin Jinhan [RK_MODE_XTS] = CRYPTO_BC_XTS, 746c3ce9937SLin Jinhan [RK_MODE_CCM] = CRYPTO_BC_CCM, 747c3ce9937SLin Jinhan [RK_MODE_GCM] = CRYPTO_BC_GCM, 748d9332f1cSLin Jinhan [RK_MODE_CMAC] = CRYPTO_BC_CMAC, 749d9332f1cSLin Jinhan [RK_MODE_CBC_MAC] = CRYPTO_BC_CBC_MAC, 75049a2135eSLin Jinhan }; 75149a2135eSLin Jinhan 752c3ce9937SLin Jinhan static inline void set_pc_len_reg(u32 chn, u64 pc_len) 753c3ce9937SLin Jinhan { 754c3ce9937SLin Jinhan u32 chn_base = CRYPTO_CH0_PC_LEN_0 + chn * 0x08; 755c3ce9937SLin Jinhan 756c3ce9937SLin Jinhan crypto_write(pc_len & 0xffffffff, chn_base); 757c3ce9937SLin Jinhan crypto_write(pc_len >> 32, chn_base + 4); 758c3ce9937SLin Jinhan } 759c3ce9937SLin Jinhan 760c3ce9937SLin Jinhan static inline void set_aad_len_reg(u32 chn, u64 pc_len) 761c3ce9937SLin Jinhan { 762c3ce9937SLin Jinhan u32 chn_base = CRYPTO_CH0_AAD_LEN_0 + chn * 0x08; 763c3ce9937SLin Jinhan 764c3ce9937SLin Jinhan crypto_write(pc_len & 0xffffffff, chn_base); 765c3ce9937SLin Jinhan crypto_write(pc_len >> 32, chn_base + 4); 766c3ce9937SLin Jinhan } 767c3ce9937SLin Jinhan 76849a2135eSLin Jinhan static inline bool is_des_mode(u32 rk_mode) 76949a2135eSLin Jinhan { 77049a2135eSLin Jinhan return (rk_mode == RK_MODE_ECB || 77149a2135eSLin Jinhan rk_mode == RK_MODE_CBC || 77249a2135eSLin Jinhan rk_mode == RK_MODE_CFB || 77349a2135eSLin Jinhan rk_mode == RK_MODE_OFB); 77449a2135eSLin Jinhan } 77549a2135eSLin Jinhan 7766b53126aSLin Jinhan static void dump_crypto_state(struct crypto_lli_desc *desc, 7776b53126aSLin Jinhan u32 tmp, u32 expt_int, 7786b53126aSLin Jinhan const u8 *in, const u8 *out, 7796b53126aSLin Jinhan u32 len, int ret) 78049a2135eSLin Jinhan { 78149a2135eSLin Jinhan IMSG("%s\n", ret == -ETIME ? "timeout" : "dismatch"); 78249a2135eSLin Jinhan 78349a2135eSLin Jinhan IMSG("CRYPTO_DMA_INT_ST = %08x, expect_int = %08x\n", 78449a2135eSLin Jinhan tmp, expt_int); 78549a2135eSLin Jinhan IMSG("data desc = %p\n", desc); 78649a2135eSLin Jinhan IMSG("\taddr_in = [%08x <=> %08x]\n", 78749a2135eSLin Jinhan desc->src_addr, (u32)virt_to_phys(in)); 78849a2135eSLin Jinhan IMSG("\taddr_out = [%08x <=> %08x]\n", 78949a2135eSLin Jinhan desc->dst_addr, (u32)virt_to_phys(out)); 79049a2135eSLin Jinhan IMSG("\tsrc_len = [%08x <=> %08x]\n", 79149a2135eSLin Jinhan desc->src_len, (u32)len); 79249a2135eSLin Jinhan IMSG("\tdst_len = %08x\n", desc->dst_len); 79349a2135eSLin Jinhan IMSG("\tdma_ctl = %08x\n", desc->dma_ctrl); 79449a2135eSLin Jinhan IMSG("\tuser_define = %08x\n", desc->user_define); 79549a2135eSLin Jinhan 79649a2135eSLin Jinhan IMSG("\n\nDMA CRYPTO_DMA_LLI_ADDR status = %08x\n", 79749a2135eSLin Jinhan crypto_read(CRYPTO_DMA_LLI_ADDR)); 79849a2135eSLin Jinhan IMSG("DMA CRYPTO_DMA_ST status = %08x\n", 79949a2135eSLin Jinhan crypto_read(CRYPTO_DMA_ST)); 80049a2135eSLin Jinhan IMSG("DMA CRYPTO_DMA_STATE status = %08x\n", 80149a2135eSLin Jinhan crypto_read(CRYPTO_DMA_STATE)); 80249a2135eSLin Jinhan IMSG("DMA CRYPTO_DMA_LLI_RADDR status = %08x\n", 80349a2135eSLin Jinhan crypto_read(CRYPTO_DMA_LLI_RADDR)); 80449a2135eSLin Jinhan IMSG("DMA CRYPTO_DMA_SRC_RADDR status = %08x\n", 80549a2135eSLin Jinhan crypto_read(CRYPTO_DMA_SRC_RADDR)); 80649a2135eSLin Jinhan IMSG("DMA CRYPTO_DMA_DST_RADDR status = %08x\n", 80749a2135eSLin Jinhan crypto_read(CRYPTO_DMA_DST_RADDR)); 80849a2135eSLin Jinhan IMSG("DMA CRYPTO_CIPHER_ST status = %08x\n", 80949a2135eSLin Jinhan crypto_read(CRYPTO_CIPHER_ST)); 81049a2135eSLin Jinhan IMSG("DMA CRYPTO_CIPHER_STATE status = %08x\n", 81149a2135eSLin Jinhan crypto_read(CRYPTO_CIPHER_STATE)); 81249a2135eSLin Jinhan IMSG("DMA CRYPTO_TAG_VALID status = %08x\n", 81349a2135eSLin Jinhan crypto_read(CRYPTO_TAG_VALID)); 81449a2135eSLin Jinhan IMSG("LOCKSTEP status = %08x\n\n", 81549a2135eSLin Jinhan crypto_read(0x618)); 81649a2135eSLin Jinhan 81749a2135eSLin Jinhan IMSG("dst %dbyte not transferred\n", 81849a2135eSLin Jinhan desc->dst_addr + desc->dst_len - 81949a2135eSLin Jinhan crypto_read(CRYPTO_DMA_DST_RADDR)); 82049a2135eSLin Jinhan } 82149a2135eSLin Jinhan 822c3ce9937SLin Jinhan static int ccm128_set_iv_reg(u32 chn, const u8 *nonce, u32 nlen) 823c3ce9937SLin Jinhan { 824c3ce9937SLin Jinhan u8 iv_buf[AES_BLOCK_SIZE]; 825c3ce9937SLin Jinhan u32 L; 826c3ce9937SLin Jinhan 827c3ce9937SLin Jinhan memset(iv_buf, 0x00, sizeof(iv_buf)); 828c3ce9937SLin Jinhan 829c3ce9937SLin Jinhan L = 15 - nlen; 830c3ce9937SLin Jinhan iv_buf[0] = ((u8)(L - 1) & 7); 831c3ce9937SLin Jinhan 832c3ce9937SLin Jinhan /* the L parameter */ 833c3ce9937SLin Jinhan L = iv_buf[0] & 7; 834c3ce9937SLin Jinhan 835c3ce9937SLin Jinhan /* nonce is too short */ 836c3ce9937SLin Jinhan if (nlen < (14 - L)) 837c3ce9937SLin Jinhan return -EINVAL; 838c3ce9937SLin Jinhan 839c3ce9937SLin Jinhan /* clear aad flag */ 840c3ce9937SLin Jinhan iv_buf[0] &= ~0x40; 841c3ce9937SLin Jinhan memcpy(&iv_buf[1], nonce, 14 - L); 842c3ce9937SLin Jinhan 843c3ce9937SLin Jinhan set_iv_reg(chn, iv_buf, AES_BLOCK_SIZE); 844c3ce9937SLin Jinhan 845c3ce9937SLin Jinhan return 0; 846c3ce9937SLin Jinhan } 847c3ce9937SLin Jinhan 848c3ce9937SLin Jinhan static void ccm_aad_padding(u32 aad_len, u8 *padding, u32 *padding_size) 849c3ce9937SLin Jinhan { 850c3ce9937SLin Jinhan u32 i; 851c3ce9937SLin Jinhan 8522db770efSLin Jinhan if (aad_len == 0) { 8532db770efSLin Jinhan *padding_size = 0; 8542db770efSLin Jinhan return; 8552db770efSLin Jinhan } 8562db770efSLin Jinhan 857c3ce9937SLin Jinhan i = aad_len < (0x10000 - 0x100) ? 2 : 6; 858c3ce9937SLin Jinhan 859c3ce9937SLin Jinhan if (i == 2) { 860c3ce9937SLin Jinhan padding[0] = (u8)(aad_len >> 8); 861c3ce9937SLin Jinhan padding[1] = (u8)aad_len; 862c3ce9937SLin Jinhan } else { 863c3ce9937SLin Jinhan padding[0] = 0xFF; 864c3ce9937SLin Jinhan padding[1] = 0xFE; 865c3ce9937SLin Jinhan padding[2] = (u8)(aad_len >> 24); 866c3ce9937SLin Jinhan padding[3] = (u8)(aad_len >> 16); 867c3ce9937SLin Jinhan padding[4] = (u8)(aad_len >> 8); 868c3ce9937SLin Jinhan } 869c3ce9937SLin Jinhan 870c3ce9937SLin Jinhan *padding_size = i; 871c3ce9937SLin Jinhan } 872c3ce9937SLin Jinhan 8732db770efSLin Jinhan static int ccm_compose_aad_iv(u8 *aad_iv, u32 data_len, u32 aad_len, u32 tag_size) 874c3ce9937SLin Jinhan { 875c3ce9937SLin Jinhan aad_iv[0] |= ((u8)(((tag_size - 2) / 2) & 7) << 3); 876c3ce9937SLin Jinhan 877c3ce9937SLin Jinhan aad_iv[12] = (u8)(data_len >> 24); 878c3ce9937SLin Jinhan aad_iv[13] = (u8)(data_len >> 16); 879c3ce9937SLin Jinhan aad_iv[14] = (u8)(data_len >> 8); 880c3ce9937SLin Jinhan aad_iv[15] = (u8)data_len; 881c3ce9937SLin Jinhan 8822db770efSLin Jinhan if (aad_len) 883c3ce9937SLin Jinhan aad_iv[0] |= 0x40; //set aad flag 884c3ce9937SLin Jinhan 885c3ce9937SLin Jinhan return 0; 886c3ce9937SLin Jinhan } 887c3ce9937SLin Jinhan 88849a2135eSLin Jinhan static int hw_cipher_init(u32 chn, const u8 *key, const u8 *twk_key, 88949a2135eSLin Jinhan u32 key_len, const u8 *iv, u32 iv_len, 89049a2135eSLin Jinhan u32 algo, u32 mode, bool enc) 89149a2135eSLin Jinhan { 89249a2135eSLin Jinhan u32 rk_mode = RK_GET_RK_MODE(mode); 89349a2135eSLin Jinhan u32 key_chn_sel = chn; 89449a2135eSLin Jinhan u32 reg_ctrl = 0; 895eecb3765SLin Jinhan bool use_otpkey = false; 896eecb3765SLin Jinhan 897eecb3765SLin Jinhan if (!key && key_len) 898eecb3765SLin Jinhan use_otpkey = true; 89949a2135eSLin Jinhan 90049a2135eSLin Jinhan IMSG("%s: key addr is %p, key_len is %d, iv addr is %p", 90149a2135eSLin Jinhan __func__, key, key_len, iv); 90249a2135eSLin Jinhan if (rk_mode >= RK_MODE_MAX) 90349a2135eSLin Jinhan return -EINVAL; 90449a2135eSLin Jinhan 90549a2135eSLin Jinhan switch (algo) { 90649a2135eSLin Jinhan case CRYPTO_DES: 90749a2135eSLin Jinhan if (key_len > DES_BLOCK_SIZE) 90849a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_TDES; 90949a2135eSLin Jinhan else 91049a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_DES; 91149a2135eSLin Jinhan break; 91249a2135eSLin Jinhan case CRYPTO_AES: 91349a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_AES; 91449a2135eSLin Jinhan break; 91549a2135eSLin Jinhan case CRYPTO_SM4: 91649a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_SM4; 91749a2135eSLin Jinhan break; 91849a2135eSLin Jinhan default: 91949a2135eSLin Jinhan return -EINVAL; 92049a2135eSLin Jinhan } 92149a2135eSLin Jinhan 92249a2135eSLin Jinhan if (algo == CRYPTO_AES || algo == CRYPTO_SM4) { 92349a2135eSLin Jinhan switch (key_len) { 92449a2135eSLin Jinhan case AES_KEYSIZE_128: 92549a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_128_bit_key; 92649a2135eSLin Jinhan break; 92749a2135eSLin Jinhan case AES_KEYSIZE_192: 92849a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_192_bit_key; 92949a2135eSLin Jinhan break; 93049a2135eSLin Jinhan case AES_KEYSIZE_256: 93149a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_256_bit_key; 93249a2135eSLin Jinhan break; 93349a2135eSLin Jinhan default: 93449a2135eSLin Jinhan return -EINVAL; 93549a2135eSLin Jinhan } 93649a2135eSLin Jinhan } 93749a2135eSLin Jinhan 93849a2135eSLin Jinhan reg_ctrl |= rk_mode2bc_mode[rk_mode]; 93949a2135eSLin Jinhan if (!enc) 94049a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_DECRYPT; 94149a2135eSLin Jinhan 94249a2135eSLin Jinhan /* write key data to reg */ 943eecb3765SLin Jinhan if (!use_otpkey) { 94449a2135eSLin Jinhan write_key_reg(key_chn_sel, key, key_len); 945eecb3765SLin Jinhan crypto_write(CRYPTO_SEL_USER, CRYPTO_KEY_SEL); 946eecb3765SLin Jinhan } else { 947eecb3765SLin Jinhan crypto_write(CRYPTO_SEL_KEYTABLE, CRYPTO_KEY_SEL); 948eecb3765SLin Jinhan } 94949a2135eSLin Jinhan 95049a2135eSLin Jinhan /* write twk key for xts mode */ 95149a2135eSLin Jinhan if (rk_mode == RK_MODE_XTS) 95249a2135eSLin Jinhan write_key_reg(key_chn_sel + 4, twk_key, key_len); 95349a2135eSLin Jinhan 95449a2135eSLin Jinhan /* set iv reg */ 955c3ce9937SLin Jinhan if (rk_mode == RK_MODE_CCM) 956c3ce9937SLin Jinhan ccm128_set_iv_reg(chn, iv, iv_len); 957c3ce9937SLin Jinhan else 95849a2135eSLin Jinhan set_iv_reg(chn, iv, iv_len); 95949a2135eSLin Jinhan 96049a2135eSLin Jinhan /* din_swap set 1, dout_swap set 1, default 1. */ 96149a2135eSLin Jinhan crypto_write(0x00030003, CRYPTO_FIFO_CTL); 962fe0c4b19SLin Jinhan crypto_write(0, CRYPTO_DMA_INT_EN); 96349a2135eSLin Jinhan 96449a2135eSLin Jinhan crypto_write(reg_ctrl | CRYPTO_WRITE_MASK_ALL, CRYPTO_BC_CTL); 96549a2135eSLin Jinhan 96649a2135eSLin Jinhan return 0; 96749a2135eSLin Jinhan } 96849a2135eSLin Jinhan 96949a2135eSLin Jinhan static int hw_cipher_crypt(const u8 *in, u8 *out, u64 len, 970c3ce9937SLin Jinhan const u8 *aad, u32 aad_len, 971c3ce9937SLin Jinhan u8 *tag, u32 tag_len, u32 mode) 97249a2135eSLin Jinhan { 973c3ce9937SLin Jinhan struct crypto_lli_desc *data_desc = NULL, *aad_desc = NULL; 974c3ce9937SLin Jinhan u8 *dma_in = NULL, *dma_out = NULL, *aad_tmp = NULL; 97549a2135eSLin Jinhan u32 rk_mode = RK_GET_RK_MODE(mode); 97649a2135eSLin Jinhan u32 reg_ctrl = 0, tmp_len = 0; 97749a2135eSLin Jinhan u32 expt_int = 0, mask = 0; 97849a2135eSLin Jinhan u32 key_chn = g_key_chn; 97949a2135eSLin Jinhan u32 tmp, dst_len = 0; 98049a2135eSLin Jinhan int ret = -1; 98149a2135eSLin Jinhan 98249a2135eSLin Jinhan if (rk_mode == RK_MODE_CTS && len <= AES_BLOCK_SIZE) { 98349a2135eSLin Jinhan printf("CTS mode length %u < 16Byte\n", (u32)len); 98449a2135eSLin Jinhan return -EINVAL; 98549a2135eSLin Jinhan } 98649a2135eSLin Jinhan 98749a2135eSLin Jinhan tmp_len = (rk_mode == RK_MODE_CTR) ? ROUNDUP(len, AES_BLOCK_SIZE) : len; 98849a2135eSLin Jinhan 98949a2135eSLin Jinhan data_desc = align_malloc(sizeof(*data_desc), LLI_ADDR_ALIGN_SIZE); 99049a2135eSLin Jinhan if (!data_desc) 99149a2135eSLin Jinhan goto exit; 99249a2135eSLin Jinhan 99349a2135eSLin Jinhan if (IS_ALIGNED((ulong)in, DATA_ADDR_ALIGN_SIZE) && tmp_len == len) 99449a2135eSLin Jinhan dma_in = (void *)in; 99549a2135eSLin Jinhan else 99649a2135eSLin Jinhan dma_in = align_malloc(tmp_len, DATA_ADDR_ALIGN_SIZE); 99749a2135eSLin Jinhan if (!dma_in) 99849a2135eSLin Jinhan goto exit; 99949a2135eSLin Jinhan 100049a2135eSLin Jinhan if (out) { 100149a2135eSLin Jinhan if (IS_ALIGNED((ulong)out, DATA_ADDR_ALIGN_SIZE) && 100249a2135eSLin Jinhan tmp_len == len) 100349a2135eSLin Jinhan dma_out = out; 100449a2135eSLin Jinhan else 100549a2135eSLin Jinhan dma_out = align_malloc(tmp_len, DATA_ADDR_ALIGN_SIZE); 100649a2135eSLin Jinhan if (!dma_out) 100749a2135eSLin Jinhan goto exit; 100849a2135eSLin Jinhan dst_len = tmp_len; 100949a2135eSLin Jinhan } 101049a2135eSLin Jinhan 101149a2135eSLin Jinhan memset(data_desc, 0x00, sizeof(*data_desc)); 101249a2135eSLin Jinhan if (dma_in != in) 101349a2135eSLin Jinhan memcpy(dma_in, in, len); 101449a2135eSLin Jinhan 101549a2135eSLin Jinhan data_desc->src_addr = (u32)virt_to_phys(dma_in); 101649a2135eSLin Jinhan data_desc->src_len = tmp_len; 101749a2135eSLin Jinhan data_desc->dst_addr = (u32)virt_to_phys(dma_out); 101849a2135eSLin Jinhan data_desc->dst_len = dst_len; 1019d9332f1cSLin Jinhan data_desc->dma_ctrl = LLI_DMA_CTRL_LAST; 1020d9332f1cSLin Jinhan 1021d9332f1cSLin Jinhan if (IS_MAC_MODE(rk_mode)) { 1022d9332f1cSLin Jinhan expt_int = CRYPTO_LIST_DONE_INT_ST; 1023d9332f1cSLin Jinhan data_desc->dma_ctrl |= LLI_DMA_CTRL_LIST_DONE; 1024d9332f1cSLin Jinhan } else { 102549a2135eSLin Jinhan expt_int = CRYPTO_DST_ITEM_DONE_INT_ST; 1026d9332f1cSLin Jinhan data_desc->dma_ctrl |= LLI_DMA_CTRL_DST_DONE; 1027d9332f1cSLin Jinhan } 102849a2135eSLin Jinhan 1029ce7f4cd6SLin Jinhan data_desc->user_define = LLI_USER_CIPHER_START | 1030afdbec36SLin Jinhan LLI_USER_STRING_START | 1031c3ce9937SLin Jinhan LLI_USER_STRING_LAST | 1032c3ce9937SLin Jinhan (key_chn << 4); 1033afdbec36SLin Jinhan crypto_write((u32)virt_to_phys(data_desc), CRYPTO_DMA_LLI_ADDR); 1034afdbec36SLin Jinhan 1035afdbec36SLin Jinhan if (rk_mode == RK_MODE_CCM || rk_mode == RK_MODE_GCM) { 1036afdbec36SLin Jinhan u32 aad_tmp_len = 0; 1037c3ce9937SLin Jinhan 1038c3ce9937SLin Jinhan aad_desc = align_malloc(sizeof(*aad_desc), LLI_ADDR_ALIGN_SIZE); 1039c3ce9937SLin Jinhan if (!aad_desc) 1040c3ce9937SLin Jinhan goto exit; 1041c3ce9937SLin Jinhan 1042c3ce9937SLin Jinhan memset(aad_desc, 0x00, sizeof(*aad_desc)); 1043c3ce9937SLin Jinhan aad_desc->next_addr = (u32)virt_to_phys(data_desc); 1044ce7f4cd6SLin Jinhan aad_desc->user_define = LLI_USER_CIPHER_START | 1045c3ce9937SLin Jinhan LLI_USER_STRING_START | 1046c3ce9937SLin Jinhan LLI_USER_STRING_LAST | 1047c3ce9937SLin Jinhan LLI_USER_STRING_AAD | 1048c3ce9937SLin Jinhan (key_chn << 4); 1049c3ce9937SLin Jinhan 1050c3ce9937SLin Jinhan if (rk_mode == RK_MODE_CCM) { 1051c3ce9937SLin Jinhan u8 padding[AES_BLOCK_SIZE]; 1052c3ce9937SLin Jinhan u32 padding_size = 0; 1053c3ce9937SLin Jinhan 1054c3ce9937SLin Jinhan memset(padding, 0x00, sizeof(padding)); 1055c3ce9937SLin Jinhan ccm_aad_padding(aad_len, padding, &padding_size); 1056c3ce9937SLin Jinhan 1057c3ce9937SLin Jinhan aad_tmp_len = aad_len + AES_BLOCK_SIZE + padding_size; 1058c3ce9937SLin Jinhan aad_tmp_len = ROUNDUP(aad_tmp_len, AES_BLOCK_SIZE); 1059c3ce9937SLin Jinhan aad_tmp = align_malloc(aad_tmp_len, 1060c3ce9937SLin Jinhan DATA_ADDR_ALIGN_SIZE); 1061c3ce9937SLin Jinhan if (!aad_tmp) 1062c3ce9937SLin Jinhan goto exit; 1063c3ce9937SLin Jinhan 10642db770efSLin Jinhan /* clear last block */ 1065c3ce9937SLin Jinhan memset(aad_tmp + aad_tmp_len - AES_BLOCK_SIZE, 1066c3ce9937SLin Jinhan 0x00, AES_BLOCK_SIZE); 10672db770efSLin Jinhan 10682db770efSLin Jinhan /* read iv data from reg */ 10692db770efSLin Jinhan get_iv_reg(key_chn, aad_tmp, AES_BLOCK_SIZE); 10702db770efSLin Jinhan ccm_compose_aad_iv(aad_tmp, tmp_len, aad_len, tag_len); 10712db770efSLin Jinhan memcpy(aad_tmp + AES_BLOCK_SIZE, padding, padding_size); 10722db770efSLin Jinhan 1073c3ce9937SLin Jinhan memcpy(aad_tmp + AES_BLOCK_SIZE + padding_size, 1074c3ce9937SLin Jinhan aad, aad_len); 1075c3ce9937SLin Jinhan } else { 1076c3ce9937SLin Jinhan aad_tmp_len = aad_len; 1077b83c40a4SLin Jinhan if (IS_ALIGNED((ulong)aad, DATA_ADDR_ALIGN_SIZE)) { 1078b83c40a4SLin Jinhan aad_tmp = (void *)aad; 1079b83c40a4SLin Jinhan } else { 1080c3ce9937SLin Jinhan aad_tmp = align_malloc(aad_tmp_len, 1081c3ce9937SLin Jinhan DATA_ADDR_ALIGN_SIZE); 1082c3ce9937SLin Jinhan if (!aad_tmp) 1083c3ce9937SLin Jinhan goto exit; 1084c3ce9937SLin Jinhan 1085c3ce9937SLin Jinhan memcpy(aad_tmp, aad, aad_tmp_len); 1086b83c40a4SLin Jinhan } 1087b83c40a4SLin Jinhan 1088c3ce9937SLin Jinhan set_aad_len_reg(key_chn, aad_tmp_len); 1089c3ce9937SLin Jinhan set_pc_len_reg(key_chn, tmp_len); 1090c3ce9937SLin Jinhan } 1091c3ce9937SLin Jinhan 1092c3ce9937SLin Jinhan aad_desc->src_addr = (u32)virt_to_phys(aad_tmp); 1093c3ce9937SLin Jinhan aad_desc->src_len = aad_tmp_len; 1094afdbec36SLin Jinhan 1095afdbec36SLin Jinhan if (aad_tmp_len) { 1096afdbec36SLin Jinhan data_desc->user_define = LLI_USER_STRING_START | 1097afdbec36SLin Jinhan LLI_USER_STRING_LAST | 1098afdbec36SLin Jinhan (key_chn << 4); 1099c3ce9937SLin Jinhan crypto_write((u32)virt_to_phys(aad_desc), CRYPTO_DMA_LLI_ADDR); 1100c3ce9937SLin Jinhan cache_op_inner(DCACHE_AREA_CLEAN, aad_tmp, aad_tmp_len); 1101c3ce9937SLin Jinhan cache_op_inner(DCACHE_AREA_CLEAN, aad_desc, sizeof(*aad_desc)); 1102afdbec36SLin Jinhan } 1103c3ce9937SLin Jinhan } 110449a2135eSLin Jinhan 110549a2135eSLin Jinhan cache_op_inner(DCACHE_AREA_CLEAN, data_desc, sizeof(*data_desc)); 110649a2135eSLin Jinhan cache_op_inner(DCACHE_AREA_CLEAN, dma_in, tmp_len); 110749a2135eSLin Jinhan cache_op_inner(DCACHE_AREA_INVALIDATE, dma_out, tmp_len); 110849a2135eSLin Jinhan 110949a2135eSLin Jinhan /* din_swap set 1, dout_swap set 1, default 1. */ 111049a2135eSLin Jinhan crypto_write(0x00030003, CRYPTO_FIFO_CTL); 1111fe0c4b19SLin Jinhan crypto_write(0, CRYPTO_DMA_INT_EN); 111249a2135eSLin Jinhan 111349a2135eSLin Jinhan reg_ctrl = crypto_read(CRYPTO_BC_CTL) | CRYPTO_BC_ENABLE; 111449a2135eSLin Jinhan crypto_write(reg_ctrl | CRYPTO_WRITE_MASK_ALL, CRYPTO_BC_CTL); 111549a2135eSLin Jinhan crypto_write(0x00010001, CRYPTO_DMA_CTL);//start 111649a2135eSLin Jinhan 111749a2135eSLin Jinhan mask = ~(mask | CRYPTO_SYNC_LOCKSTEP_INT_ST); 111849a2135eSLin Jinhan 111949a2135eSLin Jinhan /* wait calc ok */ 112049a2135eSLin Jinhan ret = RK_POLL_TIMEOUT(!(crypto_read(CRYPTO_DMA_INT_ST) & mask), 112149a2135eSLin Jinhan RK_CRYPTO_TIMEOUT); 112249a2135eSLin Jinhan tmp = crypto_read(CRYPTO_DMA_INT_ST); 112349a2135eSLin Jinhan crypto_write(tmp, CRYPTO_DMA_INT_ST); 112449a2135eSLin Jinhan 112549a2135eSLin Jinhan if ((tmp & mask) == expt_int) { 112649a2135eSLin Jinhan if (out && out != dma_out) 112749a2135eSLin Jinhan memcpy(out, dma_out, len); 1128d9332f1cSLin Jinhan 1129d9332f1cSLin Jinhan if (IS_NEED_TAG(rk_mode)) { 1130d9332f1cSLin Jinhan ret = WAIT_TAG_VALID(key_chn, RK_CRYPTO_TIMEOUT); 1131d9332f1cSLin Jinhan get_tag_from_reg(key_chn, tag, AES_BLOCK_SIZE); 1132d9332f1cSLin Jinhan } 113349a2135eSLin Jinhan } else { 11346b53126aSLin Jinhan dump_crypto_state(data_desc, tmp, expt_int, in, out, len, ret); 113549a2135eSLin Jinhan ret = -1; 113649a2135eSLin Jinhan } 113749a2135eSLin Jinhan 113849a2135eSLin Jinhan exit: 113949a2135eSLin Jinhan crypto_write(0xffff0000, CRYPTO_BC_CTL);//bc_ctl disable 114049a2135eSLin Jinhan align_free(data_desc); 1141c3ce9937SLin Jinhan align_free(aad_desc); 1142b83c40a4SLin Jinhan if (dma_in != in) 114349a2135eSLin Jinhan align_free(dma_in); 1144b83c40a4SLin Jinhan if (out && dma_out != out) 114549a2135eSLin Jinhan align_free(dma_out); 1146b83c40a4SLin Jinhan if (aad && aad != aad_tmp) 1147b83c40a4SLin Jinhan align_free(aad_tmp); 114849a2135eSLin Jinhan 114949a2135eSLin Jinhan return ret; 115049a2135eSLin Jinhan } 115149a2135eSLin Jinhan 115249a2135eSLin Jinhan static int hw_aes_init(u32 chn, const u8 *key, const u8 *twk_key, u32 key_len, 115349a2135eSLin Jinhan const u8 *iv, u32 iv_len, u32 mode, bool enc) 115449a2135eSLin Jinhan { 115549a2135eSLin Jinhan u32 rk_mode = RK_GET_RK_MODE(mode); 115649a2135eSLin Jinhan 1157d9332f1cSLin Jinhan if (rk_mode > RK_MODE_XTS) 1158d9332f1cSLin Jinhan return -EINVAL; 1159d9332f1cSLin Jinhan 116049a2135eSLin Jinhan if (iv_len > AES_BLOCK_SIZE) 116149a2135eSLin Jinhan return -EINVAL; 116249a2135eSLin Jinhan 1163d9332f1cSLin Jinhan if (IS_NEED_IV(rk_mode)) { 116449a2135eSLin Jinhan if (!iv || iv_len != AES_BLOCK_SIZE) 116549a2135eSLin Jinhan return -EINVAL; 116649a2135eSLin Jinhan } else { 116749a2135eSLin Jinhan iv_len = 0; 116849a2135eSLin Jinhan } 116949a2135eSLin Jinhan 117049a2135eSLin Jinhan if (rk_mode == RK_MODE_XTS) { 117149a2135eSLin Jinhan if (key_len != AES_KEYSIZE_128 && key_len != AES_KEYSIZE_256) 117249a2135eSLin Jinhan return -EINVAL; 117349a2135eSLin Jinhan 117449a2135eSLin Jinhan if (!key || !twk_key) 117549a2135eSLin Jinhan return -EINVAL; 117649a2135eSLin Jinhan } else { 117749a2135eSLin Jinhan if (key_len != AES_KEYSIZE_128 && 117849a2135eSLin Jinhan key_len != AES_KEYSIZE_192 && 117949a2135eSLin Jinhan key_len != AES_KEYSIZE_256) 118049a2135eSLin Jinhan return -EINVAL; 118149a2135eSLin Jinhan } 118249a2135eSLin Jinhan 118349a2135eSLin Jinhan return hw_cipher_init(chn, key, twk_key, key_len, iv, iv_len, 118449a2135eSLin Jinhan CRYPTO_AES, mode, enc); 118549a2135eSLin Jinhan } 118649a2135eSLin Jinhan 118749a2135eSLin Jinhan static int hw_sm4_init(u32 chn, const u8 *key, const u8 *twk_key, u32 key_len, 118849a2135eSLin Jinhan const u8 *iv, u32 iv_len, u32 mode, bool enc) 118949a2135eSLin Jinhan { 119049a2135eSLin Jinhan u32 rk_mode = RK_GET_RK_MODE(mode); 119149a2135eSLin Jinhan 1192d9332f1cSLin Jinhan if (rk_mode > RK_MODE_XTS) 1193d9332f1cSLin Jinhan return -EINVAL; 1194d9332f1cSLin Jinhan 119549a2135eSLin Jinhan if (iv_len > SM4_BLOCK_SIZE || key_len != SM4_KEYSIZE) 119649a2135eSLin Jinhan return -EINVAL; 119749a2135eSLin Jinhan 1198d9332f1cSLin Jinhan if (IS_NEED_IV(rk_mode)) { 119949a2135eSLin Jinhan if (!iv || iv_len != SM4_BLOCK_SIZE) 120049a2135eSLin Jinhan return -EINVAL; 120149a2135eSLin Jinhan } else { 120249a2135eSLin Jinhan iv_len = 0; 120349a2135eSLin Jinhan } 120449a2135eSLin Jinhan 120549a2135eSLin Jinhan if (rk_mode == RK_MODE_XTS) { 120649a2135eSLin Jinhan if (!key || !twk_key) 120749a2135eSLin Jinhan return -EINVAL; 120849a2135eSLin Jinhan } 120949a2135eSLin Jinhan 121049a2135eSLin Jinhan return hw_cipher_init(chn, key, twk_key, key_len, iv, iv_len, 121149a2135eSLin Jinhan CRYPTO_SM4, mode, enc); 121249a2135eSLin Jinhan } 121349a2135eSLin Jinhan 121449a2135eSLin Jinhan int rk_crypto_des(struct udevice *dev, u32 mode, const u8 *key, u32 key_len, 121549a2135eSLin Jinhan const u8 *iv, const u8 *in, u8 *out, u32 len, bool enc) 121649a2135eSLin Jinhan { 121749a2135eSLin Jinhan u32 rk_mode = RK_GET_RK_MODE(mode); 121849a2135eSLin Jinhan u8 tmp_key[24]; 121949a2135eSLin Jinhan int ret; 122049a2135eSLin Jinhan 122149a2135eSLin Jinhan if (!is_des_mode(rk_mode)) 122249a2135eSLin Jinhan return -EINVAL; 122349a2135eSLin Jinhan 122449a2135eSLin Jinhan if (key_len == DES_BLOCK_SIZE || key_len == 3 * DES_BLOCK_SIZE) { 122549a2135eSLin Jinhan memcpy(tmp_key, key, key_len); 122649a2135eSLin Jinhan } else if (key_len == 2 * DES_BLOCK_SIZE) { 122749a2135eSLin Jinhan memcpy(tmp_key, key, 16); 122849a2135eSLin Jinhan memcpy(tmp_key + 16, key, 8); 122949a2135eSLin Jinhan key_len = 3 * DES_BLOCK_SIZE; 123049a2135eSLin Jinhan } else { 123149a2135eSLin Jinhan return -EINVAL; 123249a2135eSLin Jinhan } 123349a2135eSLin Jinhan 123449a2135eSLin Jinhan ret = hw_cipher_init(0, tmp_key, NULL, key_len, iv, DES_BLOCK_SIZE, 123549a2135eSLin Jinhan CRYPTO_DES, mode, enc); 123649a2135eSLin Jinhan if (ret) 123749a2135eSLin Jinhan goto exit; 123849a2135eSLin Jinhan 123949a2135eSLin Jinhan ret = hw_cipher_crypt(in, out, len, NULL, 0, 124049a2135eSLin Jinhan NULL, 0, mode); 124149a2135eSLin Jinhan 124249a2135eSLin Jinhan exit: 124349a2135eSLin Jinhan return ret; 124449a2135eSLin Jinhan } 124549a2135eSLin Jinhan 124649a2135eSLin Jinhan int rk_crypto_aes(struct udevice *dev, u32 mode, 124749a2135eSLin Jinhan const u8 *key, const u8 *twk_key, u32 key_len, 124849a2135eSLin Jinhan const u8 *iv, u32 iv_len, 124949a2135eSLin Jinhan const u8 *in, u8 *out, u32 len, bool enc) 125049a2135eSLin Jinhan { 125149a2135eSLin Jinhan int ret; 125249a2135eSLin Jinhan 125349a2135eSLin Jinhan /* RV1126/RV1109 do not support aes-192 */ 125449a2135eSLin Jinhan #if defined(CONFIG_ROCKCHIP_RV1126) 125549a2135eSLin Jinhan if (key_len == AES_KEYSIZE_192) 125649a2135eSLin Jinhan return -EINVAL; 125749a2135eSLin Jinhan #endif 125849a2135eSLin Jinhan 125949a2135eSLin Jinhan ret = hw_aes_init(0, key, twk_key, key_len, iv, iv_len, mode, enc); 126049a2135eSLin Jinhan if (ret) 126149a2135eSLin Jinhan return ret; 126249a2135eSLin Jinhan 126349a2135eSLin Jinhan return hw_cipher_crypt(in, out, len, NULL, 0, 126449a2135eSLin Jinhan NULL, 0, mode); 126549a2135eSLin Jinhan } 126649a2135eSLin Jinhan 126749a2135eSLin Jinhan int rk_crypto_sm4(struct udevice *dev, u32 mode, 126849a2135eSLin Jinhan const u8 *key, const u8 *twk_key, u32 key_len, 126949a2135eSLin Jinhan const u8 *iv, u32 iv_len, 127049a2135eSLin Jinhan const u8 *in, u8 *out, u32 len, bool enc) 127149a2135eSLin Jinhan { 127249a2135eSLin Jinhan int ret; 127349a2135eSLin Jinhan 127449a2135eSLin Jinhan ret = hw_sm4_init(0, key, twk_key, key_len, iv, iv_len, mode, enc); 127549a2135eSLin Jinhan if (ret) 127649a2135eSLin Jinhan return ret; 127749a2135eSLin Jinhan 127849a2135eSLin Jinhan return hw_cipher_crypt(in, out, len, NULL, 0, NULL, 0, mode); 127949a2135eSLin Jinhan } 128049a2135eSLin Jinhan 128149a2135eSLin Jinhan int rockchip_crypto_cipher(struct udevice *dev, cipher_context *ctx, 128249a2135eSLin Jinhan const u8 *in, u8 *out, u32 len, bool enc) 128349a2135eSLin Jinhan { 1284dd7763a8SFinley Xiao int ret; 1285dd7763a8SFinley Xiao 1286dd7763a8SFinley Xiao rk_crypto_enable_clk(dev); 1287dd7763a8SFinley Xiao 128849a2135eSLin Jinhan switch (ctx->algo) { 128949a2135eSLin Jinhan case CRYPTO_DES: 1290dd7763a8SFinley Xiao ret = rk_crypto_des(dev, ctx->mode, ctx->key, ctx->key_len, 129149a2135eSLin Jinhan ctx->iv, in, out, len, enc); 12929b9c232aSLin Jinhan break; 129349a2135eSLin Jinhan case CRYPTO_AES: 1294dd7763a8SFinley Xiao ret = rk_crypto_aes(dev, ctx->mode, 129549a2135eSLin Jinhan ctx->key, ctx->twk_key, ctx->key_len, 129649a2135eSLin Jinhan ctx->iv, ctx->iv_len, in, out, len, enc); 12979b9c232aSLin Jinhan break; 129849a2135eSLin Jinhan case CRYPTO_SM4: 1299dd7763a8SFinley Xiao ret = rk_crypto_sm4(dev, ctx->mode, 130049a2135eSLin Jinhan ctx->key, ctx->twk_key, ctx->key_len, 130149a2135eSLin Jinhan ctx->iv, ctx->iv_len, in, out, len, enc); 13029b9c232aSLin Jinhan break; 130349a2135eSLin Jinhan default: 1304dd7763a8SFinley Xiao ret = -EINVAL; 13059b9c232aSLin Jinhan break; 130649a2135eSLin Jinhan } 1307dd7763a8SFinley Xiao 1308dd7763a8SFinley Xiao rk_crypto_disable_clk(dev); 1309dd7763a8SFinley Xiao 1310dd7763a8SFinley Xiao return ret; 131149a2135eSLin Jinhan } 1312d9332f1cSLin Jinhan 1313d9332f1cSLin Jinhan int rk_crypto_mac(struct udevice *dev, u32 algo, u32 mode, 1314d9332f1cSLin Jinhan const u8 *key, u32 key_len, 1315d9332f1cSLin Jinhan const u8 *in, u32 len, u8 *tag) 1316d9332f1cSLin Jinhan { 1317d9332f1cSLin Jinhan u32 rk_mode = RK_GET_RK_MODE(mode); 1318d9332f1cSLin Jinhan int ret; 1319d9332f1cSLin Jinhan 1320d9332f1cSLin Jinhan if (!IS_MAC_MODE(rk_mode)) 1321d9332f1cSLin Jinhan return -EINVAL; 1322d9332f1cSLin Jinhan 1323d9332f1cSLin Jinhan if (algo != CRYPTO_AES && algo != CRYPTO_SM4) 1324d9332f1cSLin Jinhan return -EINVAL; 1325d9332f1cSLin Jinhan 1326d9332f1cSLin Jinhan /* RV1126/RV1109 do not support aes-192 */ 1327d9332f1cSLin Jinhan #if defined(CONFIG_ROCKCHIP_RV1126) 1328d9332f1cSLin Jinhan if (algo == CRYPTO_AES && key_len == AES_KEYSIZE_192) 1329d9332f1cSLin Jinhan return -EINVAL; 1330d9332f1cSLin Jinhan #endif 1331d9332f1cSLin Jinhan 1332d9332f1cSLin Jinhan ret = hw_cipher_init(g_key_chn, key, NULL, key_len, NULL, 0, 1333d9332f1cSLin Jinhan algo, mode, true); 1334d9332f1cSLin Jinhan if (ret) 1335d9332f1cSLin Jinhan return ret; 1336d9332f1cSLin Jinhan 1337d9332f1cSLin Jinhan return hw_cipher_crypt(in, NULL, len, NULL, 0, 1338d9332f1cSLin Jinhan tag, AES_BLOCK_SIZE, mode); 1339d9332f1cSLin Jinhan } 1340d9332f1cSLin Jinhan 1341d9332f1cSLin Jinhan int rockchip_crypto_mac(struct udevice *dev, cipher_context *ctx, 1342d9332f1cSLin Jinhan const u8 *in, u32 len, u8 *tag) 1343d9332f1cSLin Jinhan { 1344dd7763a8SFinley Xiao int ret = 0; 1345dd7763a8SFinley Xiao 1346dd7763a8SFinley Xiao rk_crypto_enable_clk(dev); 1347dd7763a8SFinley Xiao 1348dd7763a8SFinley Xiao ret = rk_crypto_mac(dev, ctx->algo, ctx->mode, 1349d9332f1cSLin Jinhan ctx->key, ctx->key_len, in, len, tag); 1350dd7763a8SFinley Xiao 1351dd7763a8SFinley Xiao rk_crypto_disable_clk(dev); 1352dd7763a8SFinley Xiao 1353dd7763a8SFinley Xiao return ret; 1354d9332f1cSLin Jinhan } 1355d9332f1cSLin Jinhan 1356c3ce9937SLin Jinhan int rk_crypto_ae(struct udevice *dev, u32 algo, u32 mode, 1357c3ce9937SLin Jinhan const u8 *key, u32 key_len, const u8 *nonce, u32 nonce_len, 1358c3ce9937SLin Jinhan const u8 *in, u32 len, const u8 *aad, u32 aad_len, 1359c3ce9937SLin Jinhan u8 *out, u8 *tag) 1360c3ce9937SLin Jinhan { 1361c3ce9937SLin Jinhan u32 rk_mode = RK_GET_RK_MODE(mode); 1362c3ce9937SLin Jinhan int ret; 1363c3ce9937SLin Jinhan 1364c3ce9937SLin Jinhan if (!IS_AE_MODE(rk_mode)) 1365c3ce9937SLin Jinhan return -EINVAL; 1366c3ce9937SLin Jinhan 1367afdbec36SLin Jinhan if (len == 0) 1368afdbec36SLin Jinhan return -EINVAL; 1369afdbec36SLin Jinhan 1370c3ce9937SLin Jinhan if (algo != CRYPTO_AES && algo != CRYPTO_SM4) 1371c3ce9937SLin Jinhan return -EINVAL; 1372c3ce9937SLin Jinhan 1373c3ce9937SLin Jinhan /* RV1126/RV1109 do not support aes-192 */ 1374c3ce9937SLin Jinhan #if defined(CONFIG_ROCKCHIP_RV1126) 1375c3ce9937SLin Jinhan if (algo == CRYPTO_AES && key_len == AES_KEYSIZE_192) 1376c3ce9937SLin Jinhan return -EINVAL; 1377c3ce9937SLin Jinhan #endif 1378c3ce9937SLin Jinhan 1379c3ce9937SLin Jinhan ret = hw_cipher_init(g_key_chn, key, NULL, key_len, nonce, nonce_len, 1380c3ce9937SLin Jinhan algo, mode, true); 1381c3ce9937SLin Jinhan if (ret) 1382c3ce9937SLin Jinhan return ret; 1383c3ce9937SLin Jinhan 1384c3ce9937SLin Jinhan return hw_cipher_crypt(in, out, len, aad, aad_len, 1385c3ce9937SLin Jinhan tag, AES_BLOCK_SIZE, mode); 1386c3ce9937SLin Jinhan } 1387c3ce9937SLin Jinhan 1388c3ce9937SLin Jinhan int rockchip_crypto_ae(struct udevice *dev, cipher_context *ctx, 1389c3ce9937SLin Jinhan const u8 *in, u32 len, const u8 *aad, u32 aad_len, 1390c3ce9937SLin Jinhan u8 *out, u8 *tag) 13916b0f7484SLin Jinhan 1392c3ce9937SLin Jinhan { 1393dd7763a8SFinley Xiao int ret = 0; 1394dd7763a8SFinley Xiao 1395dd7763a8SFinley Xiao rk_crypto_enable_clk(dev); 1396dd7763a8SFinley Xiao 1397dd7763a8SFinley Xiao ret = rk_crypto_ae(dev, ctx->algo, ctx->mode, ctx->key, ctx->key_len, 1398c3ce9937SLin Jinhan ctx->iv, ctx->iv_len, in, len, 1399c3ce9937SLin Jinhan aad, aad_len, out, tag); 1400dd7763a8SFinley Xiao 1401dd7763a8SFinley Xiao rk_crypto_disable_clk(dev); 1402dd7763a8SFinley Xiao 1403dd7763a8SFinley Xiao return ret; 1404c3ce9937SLin Jinhan } 1405c3ce9937SLin Jinhan 1406*f489a6d7SJoseph Chen #if CONFIG_IS_ENABLED(DM_KEYLAD) 1407*f489a6d7SJoseph Chen int rockchip_crypto_fw_cipher(struct udevice *dev, cipher_fw_context *ctx, 1408*f489a6d7SJoseph Chen const u8 *in, u8 *out, u32 len, bool enc) 1409*f489a6d7SJoseph Chen { 1410*f489a6d7SJoseph Chen int ret; 1411*f489a6d7SJoseph Chen 1412*f489a6d7SJoseph Chen rk_crypto_enable_clk(dev); 1413*f489a6d7SJoseph Chen 1414*f489a6d7SJoseph Chen switch (ctx->algo) { 1415*f489a6d7SJoseph Chen case CRYPTO_DES: 1416*f489a6d7SJoseph Chen ret = rk_crypto_des(dev, ctx->mode, NULL, ctx->key_len, 1417*f489a6d7SJoseph Chen ctx->iv, in, out, len, enc); 1418*f489a6d7SJoseph Chen break; 1419*f489a6d7SJoseph Chen case CRYPTO_AES: 1420*f489a6d7SJoseph Chen ret = rk_crypto_aes(dev, ctx->mode, NULL, NULL, ctx->key_len, 1421*f489a6d7SJoseph Chen ctx->iv, ctx->iv_len, in, out, len, enc); 1422*f489a6d7SJoseph Chen break; 1423*f489a6d7SJoseph Chen case CRYPTO_SM4: 1424*f489a6d7SJoseph Chen ret = rk_crypto_sm4(dev, ctx->mode, NULL, NULL, ctx->key_len, 1425*f489a6d7SJoseph Chen ctx->iv, ctx->iv_len, in, out, len, enc); 1426*f489a6d7SJoseph Chen break; 1427*f489a6d7SJoseph Chen default: 1428*f489a6d7SJoseph Chen ret = -EINVAL; 1429*f489a6d7SJoseph Chen break; 1430*f489a6d7SJoseph Chen } 1431*f489a6d7SJoseph Chen 1432*f489a6d7SJoseph Chen rk_crypto_disable_clk(dev); 1433*f489a6d7SJoseph Chen 1434*f489a6d7SJoseph Chen return ret; 1435*f489a6d7SJoseph Chen } 1436*f489a6d7SJoseph Chen 1437eecb3765SLin Jinhan static ulong rockchip_crypto_keytable_addr(struct udevice *dev) 1438eecb3765SLin Jinhan { 1439eecb3765SLin Jinhan return CRYPTO_S_BY_KEYLAD_BASE + CRYPTO_CH0_KEY_0; 1440eecb3765SLin Jinhan } 1441*f489a6d7SJoseph Chen #endif 144249a2135eSLin Jinhan #endif 144349a2135eSLin Jinhan 1444864e581cSLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_RSA) 1445b353a43cSLin Jinhan static int rockchip_crypto_rsa_verify(struct udevice *dev, rsa_key *ctx, 1446b353a43cSLin Jinhan u8 *sign, u8 *output) 1447b353a43cSLin Jinhan { 1448b353a43cSLin Jinhan struct mpa_num *mpa_m = NULL, *mpa_e = NULL, *mpa_n = NULL; 1449b353a43cSLin Jinhan struct mpa_num *mpa_c = NULL, *mpa_result = NULL; 1450b353a43cSLin Jinhan u32 n_bits, n_words; 1451b353a43cSLin Jinhan int ret; 1452b353a43cSLin Jinhan 1453b353a43cSLin Jinhan if (!ctx) 1454b353a43cSLin Jinhan return -EINVAL; 1455b353a43cSLin Jinhan 1456b353a43cSLin Jinhan if (ctx->algo != CRYPTO_RSA512 && 1457b353a43cSLin Jinhan ctx->algo != CRYPTO_RSA1024 && 1458b353a43cSLin Jinhan ctx->algo != CRYPTO_RSA2048 && 1459b353a43cSLin Jinhan ctx->algo != CRYPTO_RSA3072 && 1460b353a43cSLin Jinhan ctx->algo != CRYPTO_RSA4096) 1461b353a43cSLin Jinhan return -EINVAL; 1462b353a43cSLin Jinhan 1463b353a43cSLin Jinhan n_bits = crypto_algo_nbits(ctx->algo); 1464b353a43cSLin Jinhan n_words = BITS2WORD(n_bits); 1465b353a43cSLin Jinhan 1466549a74f7SLin Jinhan ret = rk_mpa_alloc(&mpa_m, sign, n_words); 1467b353a43cSLin Jinhan if (ret) 1468b353a43cSLin Jinhan goto exit; 1469b353a43cSLin Jinhan 1470549a74f7SLin Jinhan ret = rk_mpa_alloc(&mpa_e, ctx->e, n_words); 1471549a74f7SLin Jinhan if (ret) 1472549a74f7SLin Jinhan goto exit; 1473b353a43cSLin Jinhan 1474549a74f7SLin Jinhan ret = rk_mpa_alloc(&mpa_n, ctx->n, n_words); 1475549a74f7SLin Jinhan if (ret) 1476549a74f7SLin Jinhan goto exit; 1477549a74f7SLin Jinhan 1478549a74f7SLin Jinhan if (ctx->c) { 1479549a74f7SLin Jinhan ret = rk_mpa_alloc(&mpa_c, ctx->c, n_words); 1480549a74f7SLin Jinhan if (ret) 1481549a74f7SLin Jinhan goto exit; 1482549a74f7SLin Jinhan } 1483549a74f7SLin Jinhan 1484549a74f7SLin Jinhan ret = rk_mpa_alloc(&mpa_result, NULL, n_words); 1485549a74f7SLin Jinhan if (ret) 1486549a74f7SLin Jinhan goto exit; 1487b353a43cSLin Jinhan 1488dd7763a8SFinley Xiao rk_crypto_enable_clk(dev); 1489b353a43cSLin Jinhan ret = rk_exptmod_np(mpa_m, mpa_e, mpa_n, mpa_c, mpa_result); 1490b353a43cSLin Jinhan if (!ret) 1491549a74f7SLin Jinhan memcpy(output, mpa_result->d, BITS2BYTE(n_bits)); 1492dd7763a8SFinley Xiao rk_crypto_disable_clk(dev); 1493b353a43cSLin Jinhan 1494b353a43cSLin Jinhan exit: 1495b353a43cSLin Jinhan rk_mpa_free(&mpa_m); 1496b353a43cSLin Jinhan rk_mpa_free(&mpa_e); 1497b353a43cSLin Jinhan rk_mpa_free(&mpa_n); 1498b353a43cSLin Jinhan rk_mpa_free(&mpa_c); 1499b353a43cSLin Jinhan rk_mpa_free(&mpa_result); 1500b353a43cSLin Jinhan 1501b353a43cSLin Jinhan return ret; 1502b353a43cSLin Jinhan } 1503864e581cSLin Jinhan #endif 1504b353a43cSLin Jinhan 150502b4cf42SLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_EC) 150602b4cf42SLin Jinhan static int rockchip_crypto_ec_verify(struct udevice *dev, ec_key *ctx, 150702b4cf42SLin Jinhan u8 *hash, u32 hash_len, u8 *sign) 150802b4cf42SLin Jinhan { 150902b4cf42SLin Jinhan struct mpa_num *bn_sign = NULL; 151002b4cf42SLin Jinhan struct rk_ecp_point point_P, point_sign; 151102b4cf42SLin Jinhan u32 n_bits, n_words; 151202b4cf42SLin Jinhan int ret; 151302b4cf42SLin Jinhan 151402b4cf42SLin Jinhan if (!ctx) 151502b4cf42SLin Jinhan return -EINVAL; 151602b4cf42SLin Jinhan 151702b4cf42SLin Jinhan if (ctx->algo != CRYPTO_SM2 && 151802b4cf42SLin Jinhan ctx->algo != CRYPTO_ECC_192R1 && 151902b4cf42SLin Jinhan ctx->algo != CRYPTO_ECC_224R1 && 152002b4cf42SLin Jinhan ctx->algo != CRYPTO_ECC_256R1) 152102b4cf42SLin Jinhan return -EINVAL; 152202b4cf42SLin Jinhan 152302b4cf42SLin Jinhan n_bits = crypto_algo_nbits(ctx->algo); 152402b4cf42SLin Jinhan n_words = BITS2WORD(n_bits); 152502b4cf42SLin Jinhan 152602b4cf42SLin Jinhan ret = rk_mpa_alloc(&bn_sign, sign, n_words); 152702b4cf42SLin Jinhan if (ret) 152802b4cf42SLin Jinhan goto exit; 152902b4cf42SLin Jinhan 153002b4cf42SLin Jinhan ret = rk_mpa_alloc(&point_P.x, ctx->x, n_words); 153102b4cf42SLin Jinhan ret |= rk_mpa_alloc(&point_P.y, ctx->y, n_words); 153202b4cf42SLin Jinhan if (ret) 153302b4cf42SLin Jinhan goto exit; 153402b4cf42SLin Jinhan 153502b4cf42SLin Jinhan ret = rk_mpa_alloc(&point_sign.x, sign, n_words); 153602b4cf42SLin Jinhan ret |= rk_mpa_alloc(&point_sign.y, sign + WORD2BYTE(n_words), n_words); 153702b4cf42SLin Jinhan if (ret) 153802b4cf42SLin Jinhan goto exit; 153902b4cf42SLin Jinhan 154002b4cf42SLin Jinhan rk_crypto_enable_clk(dev); 154102b4cf42SLin Jinhan ret = rockchip_ecc_verify(ctx->algo, hash, hash_len, &point_P, &point_sign); 154202b4cf42SLin Jinhan rk_crypto_disable_clk(dev); 154302b4cf42SLin Jinhan exit: 154402b4cf42SLin Jinhan rk_mpa_free(&bn_sign); 154502b4cf42SLin Jinhan rk_mpa_free(&point_P.x); 154602b4cf42SLin Jinhan rk_mpa_free(&point_P.y); 154702b4cf42SLin Jinhan rk_mpa_free(&point_sign.x); 154802b4cf42SLin Jinhan rk_mpa_free(&point_sign.y); 154902b4cf42SLin Jinhan 155002b4cf42SLin Jinhan return ret; 155102b4cf42SLin Jinhan } 155202b4cf42SLin Jinhan #endif 155302b4cf42SLin Jinhan 1554b353a43cSLin Jinhan static const struct dm_crypto_ops rockchip_crypto_ops = { 1555b353a43cSLin Jinhan .capability = rockchip_crypto_capability, 1556b353a43cSLin Jinhan .sha_init = rockchip_crypto_sha_init, 1557b353a43cSLin Jinhan .sha_update = rockchip_crypto_sha_update, 1558b353a43cSLin Jinhan .sha_final = rockchip_crypto_sha_final, 155949a2135eSLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_RSA) 1560b353a43cSLin Jinhan .rsa_verify = rockchip_crypto_rsa_verify, 156149a2135eSLin Jinhan #endif 156202b4cf42SLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_EC) 156302b4cf42SLin Jinhan .ec_verify = rockchip_crypto_ec_verify, 156402b4cf42SLin Jinhan #endif 156549a2135eSLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_HMAC) 156649a2135eSLin Jinhan .hmac_init = rockchip_crypto_hmac_init, 156749a2135eSLin Jinhan .hmac_update = rockchip_crypto_hmac_update, 156849a2135eSLin Jinhan .hmac_final = rockchip_crypto_hmac_final, 156949a2135eSLin Jinhan #endif 157049a2135eSLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_CIPHER) 157149a2135eSLin Jinhan .cipher_crypt = rockchip_crypto_cipher, 1572d9332f1cSLin Jinhan .cipher_mac = rockchip_crypto_mac, 1573c3ce9937SLin Jinhan .cipher_ae = rockchip_crypto_ae, 1574*f489a6d7SJoseph Chen #if CONFIG_IS_ENABLED(DM_KEYLAD) 1575eecb3765SLin Jinhan .cipher_fw_crypt = rockchip_crypto_fw_cipher, 1576eecb3765SLin Jinhan .keytable_addr = rockchip_crypto_keytable_addr, 157749a2135eSLin Jinhan #endif 1578*f489a6d7SJoseph Chen #endif 1579b353a43cSLin Jinhan }; 1580b353a43cSLin Jinhan 1581b353a43cSLin Jinhan /* 1582b353a43cSLin Jinhan * Only use "clocks" to parse crypto clock id and use rockchip_get_clk(). 1583b353a43cSLin Jinhan * Because we always add crypto node in U-Boot dts, when kernel dtb enabled : 1584b353a43cSLin Jinhan * 1585b353a43cSLin Jinhan * 1. There is cru phandle mismatch between U-Boot and kernel dtb; 1586b353a43cSLin Jinhan * 2. CONFIG_OF_SPL_REMOVE_PROPS removes clock property; 1587b353a43cSLin Jinhan */ 1588b353a43cSLin Jinhan static int rockchip_crypto_ofdata_to_platdata(struct udevice *dev) 1589b353a43cSLin Jinhan { 1590b353a43cSLin Jinhan struct rockchip_crypto_priv *priv = dev_get_priv(dev); 1591b353a43cSLin Jinhan int len, ret = -EINVAL; 1592b353a43cSLin Jinhan 1593a24b2aebSLin Jinhan memset(priv, 0x00, sizeof(*priv)); 1594a24b2aebSLin Jinhan 1595a24b2aebSLin Jinhan priv->reg = (fdt_addr_t)dev_read_addr_ptr(dev); 1596a24b2aebSLin Jinhan if (priv->reg == FDT_ADDR_T_NONE) 1597a24b2aebSLin Jinhan return -EINVAL; 1598a24b2aebSLin Jinhan 1599a24b2aebSLin Jinhan crypto_base = priv->reg; 1600a24b2aebSLin Jinhan 1601a24b2aebSLin Jinhan /* if there is no clocks in dts, just skip it */ 1602b353a43cSLin Jinhan if (!dev_read_prop(dev, "clocks", &len)) { 1603b353a43cSLin Jinhan printf("Can't find \"clocks\" property\n"); 1604a24b2aebSLin Jinhan return 0; 1605b353a43cSLin Jinhan } 1606b353a43cSLin Jinhan 16076b0f7484SLin Jinhan memset(priv, 0x00, sizeof(*priv)); 1608b353a43cSLin Jinhan priv->clocks = malloc(len); 1609b353a43cSLin Jinhan if (!priv->clocks) 1610b353a43cSLin Jinhan return -ENOMEM; 1611b353a43cSLin Jinhan 1612da703fb5SLin Jinhan priv->nclocks = len / (2 * sizeof(u32)); 1613b353a43cSLin Jinhan if (dev_read_u32_array(dev, "clocks", (u32 *)priv->clocks, 1614b353a43cSLin Jinhan priv->nclocks)) { 1615b353a43cSLin Jinhan printf("Can't read \"clocks\" property\n"); 1616b353a43cSLin Jinhan ret = -EINVAL; 1617b353a43cSLin Jinhan goto exit; 1618b353a43cSLin Jinhan } 1619b353a43cSLin Jinhan 1620da703fb5SLin Jinhan if (dev_read_prop(dev, "clock-frequency", &len)) { 1621b353a43cSLin Jinhan priv->frequencies = malloc(len); 1622b353a43cSLin Jinhan if (!priv->frequencies) { 1623b353a43cSLin Jinhan ret = -ENOMEM; 1624b353a43cSLin Jinhan goto exit; 1625b353a43cSLin Jinhan } 1626a8335d81SFinley Xiao priv->freq_nclocks = len / sizeof(u32); 1627b353a43cSLin Jinhan if (dev_read_u32_array(dev, "clock-frequency", priv->frequencies, 1628da703fb5SLin Jinhan priv->freq_nclocks)) { 1629b353a43cSLin Jinhan printf("Can't read \"clock-frequency\" property\n"); 1630b353a43cSLin Jinhan ret = -EINVAL; 1631b353a43cSLin Jinhan goto exit; 1632b353a43cSLin Jinhan } 1633da703fb5SLin Jinhan } 1634b353a43cSLin Jinhan 1635b353a43cSLin Jinhan return 0; 1636b353a43cSLin Jinhan exit: 1637b353a43cSLin Jinhan if (priv->clocks) 1638b353a43cSLin Jinhan free(priv->clocks); 1639b353a43cSLin Jinhan 1640b353a43cSLin Jinhan if (priv->frequencies) 1641b353a43cSLin Jinhan free(priv->frequencies); 1642b353a43cSLin Jinhan 1643b353a43cSLin Jinhan return ret; 1644b353a43cSLin Jinhan } 1645b353a43cSLin Jinhan 16466cebff12SJoseph Chen static int rk_crypto_set_clk(struct udevice *dev) 1647b353a43cSLin Jinhan { 16486cebff12SJoseph Chen struct rockchip_crypto_priv *priv = dev_get_priv(dev); 16496cebff12SJoseph Chen struct clk clk; 1650a24b2aebSLin Jinhan int i, ret; 1651b353a43cSLin Jinhan 1652a8335d81SFinley Xiao /* use standard "assigned-clock-rates" props */ 1653a8335d81SFinley Xiao if (dev_read_size(dev, "assigned-clock-rates") > 0) 1654a8335d81SFinley Xiao return clk_set_defaults(dev); 1655da703fb5SLin Jinhan 1656a8335d81SFinley Xiao /* use "clock-frequency" props */ 1657da703fb5SLin Jinhan if (priv->freq_nclocks == 0) 1658a24b2aebSLin Jinhan return 0; 165949a2135eSLin Jinhan 1660da703fb5SLin Jinhan for (i = 0; i < priv->freq_nclocks; i++) { 16616cebff12SJoseph Chen ret = clk_get_by_index(dev, i, &clk); 16626cebff12SJoseph Chen if (ret < 0) { 16636cebff12SJoseph Chen printf("Failed to get clk index %d, ret=%d\n", i, ret); 1664b353a43cSLin Jinhan return ret; 1665b353a43cSLin Jinhan } 16666cebff12SJoseph Chen ret = clk_set_rate(&clk, priv->frequencies[i]); 1667b353a43cSLin Jinhan if (ret < 0) { 1668b353a43cSLin Jinhan printf("%s: Failed to set clk(%ld): ret=%d\n", 16696cebff12SJoseph Chen __func__, clk.id, ret); 1670b353a43cSLin Jinhan return ret; 1671b353a43cSLin Jinhan } 1672b353a43cSLin Jinhan } 1673b353a43cSLin Jinhan 1674a24b2aebSLin Jinhan return 0; 1675a24b2aebSLin Jinhan } 1676a24b2aebSLin Jinhan 1677a24b2aebSLin Jinhan static int rockchip_crypto_probe(struct udevice *dev) 1678a24b2aebSLin Jinhan { 1679a24b2aebSLin Jinhan struct rockchip_crypto_priv *priv = dev_get_priv(dev); 1680a24b2aebSLin Jinhan struct rk_crypto_soc_data *sdata; 1681a24b2aebSLin Jinhan int ret = 0; 1682a24b2aebSLin Jinhan 1683a24b2aebSLin Jinhan sdata = (struct rk_crypto_soc_data *)dev_get_driver_data(dev); 168458432b6fSLin Jinhan 168558432b6fSLin Jinhan if (sdata->dynamic_cap) 168658432b6fSLin Jinhan sdata->capability = sdata->dynamic_cap(); 168758432b6fSLin Jinhan 1688a24b2aebSLin Jinhan priv->soc_data = sdata; 1689a24b2aebSLin Jinhan 1690a24b2aebSLin Jinhan priv->hw_ctx = memalign(LLI_ADDR_ALIGN_SIZE, 1691a24b2aebSLin Jinhan sizeof(struct rk_hash_ctx)); 1692a24b2aebSLin Jinhan if (!priv->hw_ctx) 1693a24b2aebSLin Jinhan return -ENOMEM; 1694a24b2aebSLin Jinhan 16956cebff12SJoseph Chen ret = rk_crypto_set_clk(dev); 1696a24b2aebSLin Jinhan if (ret) 1697a24b2aebSLin Jinhan return ret; 1698a24b2aebSLin Jinhan 1699f2c2c30cSLin Jinhan rk_crypto_enable_clk(dev); 1700f2c2c30cSLin Jinhan 1701b353a43cSLin Jinhan hw_crypto_reset(); 1702b353a43cSLin Jinhan 1703f2c2c30cSLin Jinhan rk_crypto_disable_clk(dev); 1704f2c2c30cSLin Jinhan 1705b353a43cSLin Jinhan return 0; 1706b353a43cSLin Jinhan } 1707b353a43cSLin Jinhan 170849a2135eSLin Jinhan static const struct rk_crypto_soc_data soc_data_base = { 170949a2135eSLin Jinhan .capability = CRYPTO_MD5 | 171049a2135eSLin Jinhan CRYPTO_SHA1 | 171149a2135eSLin Jinhan CRYPTO_SHA256 | 171249a2135eSLin Jinhan CRYPTO_SHA512 | 171349a2135eSLin Jinhan CRYPTO_HMAC_MD5 | 171449a2135eSLin Jinhan CRYPTO_HMAC_SHA1 | 171549a2135eSLin Jinhan CRYPTO_HMAC_SHA256 | 171649a2135eSLin Jinhan CRYPTO_HMAC_SHA512 | 171749a2135eSLin Jinhan CRYPTO_RSA512 | 171849a2135eSLin Jinhan CRYPTO_RSA1024 | 171949a2135eSLin Jinhan CRYPTO_RSA2048 | 172049a2135eSLin Jinhan CRYPTO_RSA3072 | 172149a2135eSLin Jinhan CRYPTO_RSA4096 | 172249a2135eSLin Jinhan CRYPTO_DES | 172349a2135eSLin Jinhan CRYPTO_AES, 172449a2135eSLin Jinhan }; 172549a2135eSLin Jinhan 172649a2135eSLin Jinhan static const struct rk_crypto_soc_data soc_data_base_sm = { 172749a2135eSLin Jinhan .capability = CRYPTO_MD5 | 172849a2135eSLin Jinhan CRYPTO_SHA1 | 172949a2135eSLin Jinhan CRYPTO_SHA256 | 173049a2135eSLin Jinhan CRYPTO_SHA512 | 173149a2135eSLin Jinhan CRYPTO_SM3 | 173249a2135eSLin Jinhan CRYPTO_HMAC_MD5 | 173349a2135eSLin Jinhan CRYPTO_HMAC_SHA1 | 173449a2135eSLin Jinhan CRYPTO_HMAC_SHA256 | 173549a2135eSLin Jinhan CRYPTO_HMAC_SHA512 | 173649a2135eSLin Jinhan CRYPTO_HMAC_SM3 | 173749a2135eSLin Jinhan CRYPTO_RSA512 | 173849a2135eSLin Jinhan CRYPTO_RSA1024 | 173949a2135eSLin Jinhan CRYPTO_RSA2048 | 174049a2135eSLin Jinhan CRYPTO_RSA3072 | 174149a2135eSLin Jinhan CRYPTO_RSA4096 | 174249a2135eSLin Jinhan CRYPTO_DES | 174349a2135eSLin Jinhan CRYPTO_AES | 174449a2135eSLin Jinhan CRYPTO_SM4, 174549a2135eSLin Jinhan }; 174649a2135eSLin Jinhan 174749a2135eSLin Jinhan static const struct rk_crypto_soc_data soc_data_rk1808 = { 174849a2135eSLin Jinhan .capability = CRYPTO_MD5 | 174949a2135eSLin Jinhan CRYPTO_SHA1 | 175049a2135eSLin Jinhan CRYPTO_SHA256 | 175149a2135eSLin Jinhan CRYPTO_HMAC_MD5 | 175249a2135eSLin Jinhan CRYPTO_HMAC_SHA1 | 175349a2135eSLin Jinhan CRYPTO_HMAC_SHA256 | 175449a2135eSLin Jinhan CRYPTO_RSA512 | 175549a2135eSLin Jinhan CRYPTO_RSA1024 | 175649a2135eSLin Jinhan CRYPTO_RSA2048 | 175749a2135eSLin Jinhan CRYPTO_RSA3072 | 175849a2135eSLin Jinhan CRYPTO_RSA4096, 175949a2135eSLin Jinhan }; 176049a2135eSLin Jinhan 176158432b6fSLin Jinhan static const struct rk_crypto_soc_data soc_data_cryptov3 = { 176258432b6fSLin Jinhan .capability = 0, 176358432b6fSLin Jinhan .dynamic_cap = crypto_v3_dynamic_cap, 176458432b6fSLin Jinhan }; 176558432b6fSLin Jinhan 1766b353a43cSLin Jinhan static const struct udevice_id rockchip_crypto_ids[] = { 176749a2135eSLin Jinhan { 176849a2135eSLin Jinhan .compatible = "rockchip,px30-crypto", 176949a2135eSLin Jinhan .data = (ulong)&soc_data_base 177049a2135eSLin Jinhan }, 177149a2135eSLin Jinhan { 177249a2135eSLin Jinhan .compatible = "rockchip,rk1808-crypto", 177349a2135eSLin Jinhan .data = (ulong)&soc_data_rk1808 177449a2135eSLin Jinhan }, 177549a2135eSLin Jinhan { 177649a2135eSLin Jinhan .compatible = "rockchip,rk3308-crypto", 177749a2135eSLin Jinhan .data = (ulong)&soc_data_base 177849a2135eSLin Jinhan }, 177949a2135eSLin Jinhan { 178049a2135eSLin Jinhan .compatible = "rockchip,rv1126-crypto", 178149a2135eSLin Jinhan .data = (ulong)&soc_data_base_sm 178249a2135eSLin Jinhan }, 178349a2135eSLin Jinhan { 178449a2135eSLin Jinhan .compatible = "rockchip,rk3568-crypto", 178549a2135eSLin Jinhan .data = (ulong)&soc_data_base_sm 178649a2135eSLin Jinhan }, 17875b3e3895SLin Jinhan { 17885b3e3895SLin Jinhan .compatible = "rockchip,rk3588-crypto", 17895b3e3895SLin Jinhan .data = (ulong)&soc_data_base_sm 17905b3e3895SLin Jinhan }, 179158432b6fSLin Jinhan { 1792f93f9077SLin Jinhan .compatible = "rockchip,crypto-v3", 179358432b6fSLin Jinhan .data = (ulong)&soc_data_cryptov3 179458432b6fSLin Jinhan }, 17952bcebb1aSLin Jinhan { 17962bcebb1aSLin Jinhan .compatible = "rockchip,crypto-v4", 17972bcebb1aSLin Jinhan .data = (ulong)&soc_data_cryptov3 /* reuse crypto v3 config */ 17982bcebb1aSLin Jinhan }, 1799b353a43cSLin Jinhan { } 1800b353a43cSLin Jinhan }; 1801b353a43cSLin Jinhan 1802b353a43cSLin Jinhan U_BOOT_DRIVER(rockchip_crypto_v2) = { 1803b353a43cSLin Jinhan .name = "rockchip_crypto_v2", 1804b353a43cSLin Jinhan .id = UCLASS_CRYPTO, 1805b353a43cSLin Jinhan .of_match = rockchip_crypto_ids, 1806b353a43cSLin Jinhan .ops = &rockchip_crypto_ops, 1807b353a43cSLin Jinhan .probe = rockchip_crypto_probe, 1808b353a43cSLin Jinhan .ofdata_to_platdata = rockchip_crypto_ofdata_to_platdata, 1809b353a43cSLin Jinhan .priv_auto_alloc_size = sizeof(struct rockchip_crypto_priv), 1810b353a43cSLin Jinhan }; 1811