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 25e0c259feSLin Jinhan 2649a2135eSLin Jinhan #ifdef DEBUG 2749a2135eSLin Jinhan #define IMSG(format, ...) printf("[%s, %05d]-trace: " format "\n", \ 2849a2135eSLin Jinhan __func__, __LINE__, ##__VA_ARGS__) 2949a2135eSLin Jinhan #else 3049a2135eSLin Jinhan #define IMSG(format, ...) 3149a2135eSLin Jinhan #endif 32c48f1acfSLin Jinhan 33c48f1acfSLin Jinhan struct crypto_lli_desc { 34c48f1acfSLin Jinhan u32 src_addr; 35c48f1acfSLin Jinhan u32 src_len; 36c48f1acfSLin Jinhan u32 dst_addr; 37c48f1acfSLin Jinhan u32 dst_len; 38c48f1acfSLin Jinhan u32 user_define; 39c48f1acfSLin Jinhan u32 reserve; 40c48f1acfSLin Jinhan u32 dma_ctrl; 41c48f1acfSLin Jinhan u32 next_addr; 42c48f1acfSLin Jinhan }; 43c48f1acfSLin Jinhan 44c48f1acfSLin Jinhan struct rk_hash_ctx { 45c48f1acfSLin Jinhan struct crypto_lli_desc data_lli; /* lli desc */ 46c48f1acfSLin Jinhan struct crypto_hash_cache *hash_cache; 47c48f1acfSLin Jinhan u32 magic; /* to check ctx */ 48c48f1acfSLin Jinhan u32 algo; /* hash algo */ 49c48f1acfSLin Jinhan u8 digest_size; /* hash out length */ 50c48f1acfSLin Jinhan u8 reserved[3]; 51c48f1acfSLin Jinhan }; 52c48f1acfSLin Jinhan 5349a2135eSLin Jinhan struct rk_crypto_soc_data { 5449a2135eSLin Jinhan u32 capability; 5558432b6fSLin Jinhan u32 (*dynamic_cap)(void); 5649a2135eSLin Jinhan }; 5749a2135eSLin Jinhan 58b353a43cSLin Jinhan struct rockchip_crypto_priv { 59b353a43cSLin Jinhan fdt_addr_t reg; 60b353a43cSLin Jinhan u32 frequency; 61b353a43cSLin Jinhan char *clocks; 62b353a43cSLin Jinhan u32 *frequencies; 63b353a43cSLin Jinhan u32 nclocks; 64da703fb5SLin Jinhan u32 freq_nclocks; 65b353a43cSLin Jinhan u32 length; 661606a214SLin Jinhan struct rk_hash_ctx *hw_ctx; 6749a2135eSLin Jinhan struct rk_crypto_soc_data *soc_data; 68b353a43cSLin Jinhan }; 69b353a43cSLin Jinhan 7049a2135eSLin Jinhan #define LLI_ADDR_ALIGN_SIZE 8 7149a2135eSLin Jinhan #define DATA_ADDR_ALIGN_SIZE 8 7249a2135eSLin Jinhan #define DATA_LEN_ALIGN_SIZE 64 731606a214SLin Jinhan 74086e8fa8SLin Jinhan /* crypto timeout 500ms, must support more than 32M data per times*/ 75086e8fa8SLin Jinhan #define HASH_UPDATE_LIMIT (32 * 1024 * 1024) 7649a2135eSLin Jinhan #define RK_CRYPTO_TIMEOUT 500000 77b353a43cSLin Jinhan 7849a2135eSLin Jinhan #define RK_POLL_TIMEOUT(condition, timeout) \ 7949a2135eSLin Jinhan ({ \ 8049a2135eSLin Jinhan int time_out = timeout; \ 81b353a43cSLin Jinhan while (condition) { \ 8249a2135eSLin Jinhan if (--time_out <= 0) { \ 831606a214SLin Jinhan debug("[%s] %d: time out!\n", __func__,\ 84b353a43cSLin Jinhan __LINE__); \ 85b353a43cSLin Jinhan break; \ 86b353a43cSLin Jinhan } \ 87b353a43cSLin Jinhan udelay(1); \ 88b353a43cSLin Jinhan } \ 8949a2135eSLin Jinhan (time_out <= 0) ? -ETIMEDOUT : 0; \ 9049a2135eSLin Jinhan }) 91b353a43cSLin Jinhan 92d9332f1cSLin Jinhan #define WAIT_TAG_VALID(channel, timeout) ({ \ 93d9332f1cSLin Jinhan u32 tag_mask = CRYPTO_CH0_TAG_VALID << (channel);\ 94e0c259feSLin Jinhan int ret = 0;\ 95e0c259feSLin Jinhan if (is_check_tag_valid()) { \ 96d9332f1cSLin Jinhan ret = RK_POLL_TIMEOUT(!(crypto_read(CRYPTO_TAG_VALID) & tag_mask),\ 97d9332f1cSLin Jinhan timeout);\ 98e0c259feSLin Jinhan } \ 99d9332f1cSLin Jinhan crypto_write(crypto_read(CRYPTO_TAG_VALID) & tag_mask, CRYPTO_TAG_VALID);\ 100d9332f1cSLin Jinhan ret;\ 101d9332f1cSLin Jinhan }) 102d9332f1cSLin Jinhan 103b353a43cSLin Jinhan #define virt_to_phys(addr) (((unsigned long)addr) & 0xffffffff) 104b353a43cSLin Jinhan #define phys_to_virt(addr, area) ((unsigned long)addr) 105b353a43cSLin Jinhan 10649a2135eSLin Jinhan #define align_malloc(bytes, alignment) memalign(alignment, bytes) 107dbca2fe7SLin Jinhan #define align_free(addr) do {if (addr) free(addr);} while (0) 10849a2135eSLin Jinhan 10949a2135eSLin Jinhan #define ROUNDUP(size, alignment) round_up(size, alignment) 11049a2135eSLin Jinhan #define cache_op_inner(type, addr, size) \ 11149a2135eSLin Jinhan crypto_flush_cacheline((ulong)addr, size) 11249a2135eSLin Jinhan 113d9332f1cSLin Jinhan #define IS_NEED_IV(rk_mode) ((rk_mode) != RK_MODE_ECB && \ 114d9332f1cSLin Jinhan (rk_mode) != RK_MODE_CMAC && \ 115d9332f1cSLin Jinhan (rk_mode) != RK_MODE_CBC_MAC) 116d9332f1cSLin Jinhan 117d9332f1cSLin Jinhan #define IS_NEED_TAG(rk_mode) ((rk_mode) == RK_MODE_CMAC || \ 118c3ce9937SLin Jinhan (rk_mode) == RK_MODE_CBC_MAC || \ 119c3ce9937SLin Jinhan (rk_mode) == RK_MODE_CCM || \ 120c3ce9937SLin Jinhan (rk_mode) == RK_MODE_GCM) 121d9332f1cSLin Jinhan 122d9332f1cSLin Jinhan #define IS_MAC_MODE(rk_mode) ((rk_mode) == RK_MODE_CMAC || \ 123d9332f1cSLin Jinhan (rk_mode) == RK_MODE_CBC_MAC) 124d9332f1cSLin Jinhan 125c3ce9937SLin Jinhan #define IS_AE_MODE(rk_mode) ((rk_mode) == RK_MODE_CCM || \ 126c3ce9937SLin Jinhan (rk_mode) == RK_MODE_GCM) 127c3ce9937SLin Jinhan 128b353a43cSLin Jinhan fdt_addr_t crypto_base; 129e0c259feSLin Jinhan static uint32_t g_crypto_version; 130e0c259feSLin Jinhan 131e0c259feSLin Jinhan static inline bool is_check_hash_valid(void) 132e0c259feSLin Jinhan { 133e0c259feSLin Jinhan /* crypto < v4 need to check hash valid */ 134e0c259feSLin Jinhan return CRYPTO_MAJOR_VER(g_crypto_version) < CRYPTO_MAJOR_VER_4; 135e0c259feSLin Jinhan } 136e0c259feSLin Jinhan 137e0c259feSLin Jinhan static inline bool is_check_tag_valid(void) 138e0c259feSLin Jinhan { 139e0c259feSLin Jinhan /* crypto < v4 need to check hash valid */ 140e0c259feSLin Jinhan return CRYPTO_MAJOR_VER(g_crypto_version) < CRYPTO_MAJOR_VER_4; 141e0c259feSLin Jinhan } 142b353a43cSLin Jinhan 14349a2135eSLin Jinhan static inline void word2byte_be(u32 word, u8 *ch) 144b353a43cSLin Jinhan { 145b353a43cSLin Jinhan ch[0] = (word >> 24) & 0xff; 146b353a43cSLin Jinhan ch[1] = (word >> 16) & 0xff; 147b353a43cSLin Jinhan ch[2] = (word >> 8) & 0xff; 148b353a43cSLin Jinhan ch[3] = (word >> 0) & 0xff; 149b353a43cSLin Jinhan } 150b353a43cSLin Jinhan 15149a2135eSLin Jinhan static inline u32 byte2word_be(const u8 *ch) 15249a2135eSLin Jinhan { 15349a2135eSLin Jinhan return (*ch << 24) + (*(ch + 1) << 16) + (*(ch + 2) << 8) + *(ch + 3); 15449a2135eSLin Jinhan } 15549a2135eSLin Jinhan 15649a2135eSLin Jinhan static inline void clear_regs(u32 base, u32 words) 157b353a43cSLin Jinhan { 158b353a43cSLin Jinhan int i; 159b353a43cSLin Jinhan 160b353a43cSLin Jinhan /*clear out register*/ 16149a2135eSLin Jinhan for (i = 0; i < words; i++) 16249a2135eSLin Jinhan crypto_write(0, base + 4 * i); 16349a2135eSLin Jinhan } 16449a2135eSLin Jinhan 16549a2135eSLin Jinhan static inline void clear_key_regs(void) 16649a2135eSLin Jinhan { 16749a2135eSLin Jinhan clear_regs(CRYPTO_CH0_KEY_0, CRYPTO_KEY_CHANNEL_NUM * 4); 16849a2135eSLin Jinhan } 16949a2135eSLin Jinhan 170c3ce9937SLin Jinhan static inline void read_regs(u32 base, u8 *data, u32 data_len) 171c3ce9937SLin Jinhan { 172c3ce9937SLin Jinhan u8 tmp_buf[4]; 173c3ce9937SLin Jinhan u32 i; 174c3ce9937SLin Jinhan 175c3ce9937SLin Jinhan for (i = 0; i < data_len / 4; i++) 176c3ce9937SLin Jinhan word2byte_be(crypto_read(base + i * 4), 177c3ce9937SLin Jinhan data + i * 4); 178c3ce9937SLin Jinhan 179c3ce9937SLin Jinhan if (data_len % 4) { 180c3ce9937SLin Jinhan word2byte_be(crypto_read(base + i * 4), tmp_buf); 181c3ce9937SLin Jinhan memcpy(data + i * 4, tmp_buf, data_len % 4); 182c3ce9937SLin Jinhan } 183c3ce9937SLin Jinhan } 184c3ce9937SLin Jinhan 18549a2135eSLin Jinhan static inline void write_regs(u32 base, const u8 *data, u32 data_len) 18649a2135eSLin Jinhan { 18749a2135eSLin Jinhan u8 tmp_buf[4]; 18849a2135eSLin Jinhan u32 i; 18949a2135eSLin Jinhan 19049a2135eSLin Jinhan for (i = 0; i < data_len / 4; i++, base += 4) 19149a2135eSLin Jinhan crypto_write(byte2word_be(data + i * 4), base); 19249a2135eSLin Jinhan 19349a2135eSLin Jinhan if (data_len % 4) { 19449a2135eSLin Jinhan memset(tmp_buf, 0x00, sizeof(tmp_buf)); 19549a2135eSLin Jinhan memcpy((u8 *)tmp_buf, data + i * 4, data_len % 4); 19649a2135eSLin Jinhan crypto_write(byte2word_be(tmp_buf), base); 19749a2135eSLin Jinhan } 19849a2135eSLin Jinhan } 19949a2135eSLin Jinhan 20049a2135eSLin Jinhan static inline void write_key_reg(u32 chn, const u8 *key, u32 key_len) 20149a2135eSLin Jinhan { 20249a2135eSLin Jinhan write_regs(CRYPTO_CH0_KEY_0 + chn * 0x10, key, key_len); 20349a2135eSLin Jinhan } 20449a2135eSLin Jinhan 20549a2135eSLin Jinhan static inline void set_iv_reg(u32 chn, const u8 *iv, u32 iv_len) 20649a2135eSLin Jinhan { 20749a2135eSLin Jinhan u32 base_iv; 20849a2135eSLin Jinhan 20949a2135eSLin Jinhan base_iv = CRYPTO_CH0_IV_0 + chn * 0x10; 21049a2135eSLin Jinhan 21149a2135eSLin Jinhan /* clear iv */ 21249a2135eSLin Jinhan clear_regs(base_iv, 4); 21349a2135eSLin Jinhan 21449a2135eSLin Jinhan if (!iv || iv_len == 0) 21549a2135eSLin Jinhan return; 21649a2135eSLin Jinhan 21749a2135eSLin Jinhan write_regs(base_iv, iv, iv_len); 21849a2135eSLin Jinhan 21949a2135eSLin Jinhan crypto_write(iv_len, CRYPTO_CH0_IV_LEN_0 + 4 * chn); 220b353a43cSLin Jinhan } 221b353a43cSLin Jinhan 222c3ce9937SLin Jinhan static inline void get_iv_reg(u32 chn, u8 *iv, u32 iv_len) 223c3ce9937SLin Jinhan { 224c3ce9937SLin Jinhan u32 base_iv; 225c3ce9937SLin Jinhan 226c3ce9937SLin Jinhan base_iv = CRYPTO_CH0_IV_0 + chn * 0x10; 227c3ce9937SLin Jinhan 228c3ce9937SLin Jinhan read_regs(base_iv, iv, iv_len); 229c3ce9937SLin Jinhan } 230c3ce9937SLin Jinhan 231d9332f1cSLin Jinhan static inline void get_tag_from_reg(u32 chn, u8 *tag, u32 tag_len) 232d9332f1cSLin Jinhan { 233d9332f1cSLin Jinhan u32 i; 234d9332f1cSLin Jinhan u32 chn_base = CRYPTO_CH0_TAG_0 + 0x10 * chn; 235d9332f1cSLin Jinhan 236d9332f1cSLin Jinhan for (i = 0; i < tag_len / 4; i++, chn_base += 4) 237d9332f1cSLin Jinhan word2byte_be(crypto_read(chn_base), tag + 4 * i); 238d9332f1cSLin Jinhan } 239d9332f1cSLin Jinhan 240dd7763a8SFinley Xiao static int rk_crypto_do_enable_clk(struct udevice *dev, int enable) 241dd7763a8SFinley Xiao { 242dd7763a8SFinley Xiao struct rockchip_crypto_priv *priv = dev_get_priv(dev); 243dd7763a8SFinley Xiao struct clk clk; 244dd7763a8SFinley Xiao int i, ret; 245dd7763a8SFinley Xiao 246dd7763a8SFinley Xiao for (i = 0; i < priv->nclocks; i++) { 247dd7763a8SFinley Xiao ret = clk_get_by_index(dev, i, &clk); 248dd7763a8SFinley Xiao if (ret < 0) { 249dd7763a8SFinley Xiao printf("Failed to get clk index %d, ret=%d\n", i, ret); 250dd7763a8SFinley Xiao return ret; 251dd7763a8SFinley Xiao } 252dd7763a8SFinley Xiao 253dd7763a8SFinley Xiao if (enable) 254dd7763a8SFinley Xiao ret = clk_enable(&clk); 255dd7763a8SFinley Xiao else 256dd7763a8SFinley Xiao ret = clk_disable(&clk); 257dd7763a8SFinley Xiao if (ret < 0 && ret != -ENOSYS) { 258dd7763a8SFinley Xiao printf("Failed to enable(%d) clk(%ld): ret=%d\n", 259dd7763a8SFinley Xiao enable, clk.id, ret); 260dd7763a8SFinley Xiao return ret; 261dd7763a8SFinley Xiao } 262dd7763a8SFinley Xiao } 263dd7763a8SFinley Xiao 264dd7763a8SFinley Xiao return 0; 265dd7763a8SFinley Xiao } 266dd7763a8SFinley Xiao 267dd7763a8SFinley Xiao static int rk_crypto_enable_clk(struct udevice *dev) 268dd7763a8SFinley Xiao { 269dd7763a8SFinley Xiao return rk_crypto_do_enable_clk(dev, 1); 270dd7763a8SFinley Xiao } 271dd7763a8SFinley Xiao 272dd7763a8SFinley Xiao static int rk_crypto_disable_clk(struct udevice *dev) 273dd7763a8SFinley Xiao { 274dd7763a8SFinley Xiao return rk_crypto_do_enable_clk(dev, 0); 275dd7763a8SFinley Xiao } 276dd7763a8SFinley Xiao 27758432b6fSLin Jinhan static u32 crypto_v3_dynamic_cap(void) 27858432b6fSLin Jinhan { 27958432b6fSLin Jinhan u32 capability = 0; 28058432b6fSLin Jinhan u32 ver_reg, i; 28158432b6fSLin Jinhan struct cap_map { 28258432b6fSLin Jinhan u32 ver_offset; 28358432b6fSLin Jinhan u32 mask; 28458432b6fSLin Jinhan u32 cap_bit; 28558432b6fSLin Jinhan }; 28658432b6fSLin Jinhan const struct cap_map cap_tbl[] = { 28758432b6fSLin Jinhan {CRYPTO_HASH_VERSION, CRYPTO_HASH_MD5_FLAG, CRYPTO_MD5}, 28858432b6fSLin Jinhan {CRYPTO_HASH_VERSION, CRYPTO_HASH_SHA1_FLAG, CRYPTO_SHA1}, 28958432b6fSLin Jinhan {CRYPTO_HASH_VERSION, CRYPTO_HASH_SHA256_FLAG, CRYPTO_SHA256}, 29058432b6fSLin Jinhan {CRYPTO_HASH_VERSION, CRYPTO_HASH_SHA512_FLAG, CRYPTO_SHA512}, 29158432b6fSLin Jinhan {CRYPTO_HASH_VERSION, CRYPTO_HASH_SM3_FLAG, CRYPTO_SM3}, 29258432b6fSLin Jinhan 29358432b6fSLin Jinhan {CRYPTO_HMAC_VERSION, CRYPTO_HMAC_MD5_FLAG, CRYPTO_HMAC_MD5}, 29458432b6fSLin Jinhan {CRYPTO_HMAC_VERSION, CRYPTO_HMAC_SHA1_FLAG, CRYPTO_HMAC_SHA1}, 29558432b6fSLin Jinhan {CRYPTO_HMAC_VERSION, CRYPTO_HMAC_SHA256_FLAG, CRYPTO_HMAC_SHA256}, 29658432b6fSLin Jinhan {CRYPTO_HMAC_VERSION, CRYPTO_HMAC_SHA512_FLAG, CRYPTO_HMAC_SHA512}, 29758432b6fSLin Jinhan {CRYPTO_HMAC_VERSION, CRYPTO_HMAC_SM3_FLAG, CRYPTO_HMAC_SM3}, 29858432b6fSLin Jinhan 29958432b6fSLin Jinhan {CRYPTO_AES_VERSION, CRYPTO_AES256_FLAG, CRYPTO_AES}, 30058432b6fSLin Jinhan {CRYPTO_DES_VERSION, CRYPTO_TDES_FLAG, CRYPTO_DES}, 30158432b6fSLin Jinhan {CRYPTO_SM4_VERSION, CRYPTO_ECB_FLAG, CRYPTO_SM4}, 30258432b6fSLin Jinhan }; 30358432b6fSLin Jinhan 30458432b6fSLin Jinhan /* rsa */ 30558432b6fSLin Jinhan capability = CRYPTO_RSA512 | 30658432b6fSLin Jinhan CRYPTO_RSA1024 | 30758432b6fSLin Jinhan CRYPTO_RSA2048 | 30858432b6fSLin Jinhan CRYPTO_RSA3072 | 30958432b6fSLin Jinhan CRYPTO_RSA4096; 31058432b6fSLin Jinhan 31102b4cf42SLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_EC) 31202b4cf42SLin Jinhan capability |= (CRYPTO_SM2 | 31302b4cf42SLin Jinhan CRYPTO_ECC_192R1 | 31402b4cf42SLin Jinhan CRYPTO_ECC_224R1 | 31502b4cf42SLin Jinhan CRYPTO_ECC_256R1); 31602b4cf42SLin Jinhan #endif 31702b4cf42SLin Jinhan 31858432b6fSLin Jinhan for (i = 0; i < ARRAY_SIZE(cap_tbl); i++) { 31958432b6fSLin Jinhan ver_reg = crypto_read(cap_tbl[i].ver_offset); 32058432b6fSLin Jinhan 32158432b6fSLin Jinhan if ((ver_reg & cap_tbl[i].mask) == cap_tbl[i].mask) 32258432b6fSLin Jinhan capability |= cap_tbl[i].cap_bit; 32358432b6fSLin Jinhan } 32458432b6fSLin Jinhan 32558432b6fSLin Jinhan return capability; 32658432b6fSLin Jinhan } 32758432b6fSLin Jinhan 328b353a43cSLin Jinhan static int hw_crypto_reset(void) 329b353a43cSLin Jinhan { 33049a2135eSLin Jinhan u32 val = 0, mask = 0; 331b353a43cSLin Jinhan int ret; 332b353a43cSLin Jinhan 33349a2135eSLin Jinhan val = CRYPTO_SW_PKA_RESET | CRYPTO_SW_CC_RESET; 33449a2135eSLin Jinhan mask = val << CRYPTO_WRITE_MASK_SHIFT; 335b353a43cSLin Jinhan 336b353a43cSLin Jinhan /* reset pka and crypto modules*/ 33749a2135eSLin Jinhan crypto_write(val | mask, CRYPTO_RST_CTL); 338b353a43cSLin Jinhan 339b353a43cSLin Jinhan /* wait reset compelete */ 34049a2135eSLin Jinhan ret = RK_POLL_TIMEOUT(crypto_read(CRYPTO_RST_CTL), RK_CRYPTO_TIMEOUT); 34149a2135eSLin Jinhan 342e0c259feSLin Jinhan g_crypto_version = crypto_read(CRYPTO_CRYPTO_VERSION_NEW); 343e0c259feSLin Jinhan 344b353a43cSLin Jinhan return ret; 345b353a43cSLin Jinhan } 346b353a43cSLin Jinhan 347b353a43cSLin Jinhan static void hw_hash_clean_ctx(struct rk_hash_ctx *ctx) 348b353a43cSLin Jinhan { 349b353a43cSLin Jinhan /* clear hash status */ 350b353a43cSLin Jinhan crypto_write(CRYPTO_WRITE_MASK_ALL | 0, CRYPTO_HASH_CTL); 351b353a43cSLin Jinhan 3521606a214SLin Jinhan assert(ctx); 3531606a214SLin Jinhan assert(ctx->magic == RK_HASH_CTX_MAGIC); 3541606a214SLin Jinhan 355c48f1acfSLin Jinhan crypto_hash_cache_free(ctx->hash_cache); 3561606a214SLin Jinhan 3571606a214SLin Jinhan memset(ctx, 0x00, sizeof(*ctx)); 358b353a43cSLin Jinhan } 359b353a43cSLin Jinhan 360c48f1acfSLin Jinhan static int rk_hash_init(void *hw_ctx, u32 algo) 361b353a43cSLin Jinhan { 362b353a43cSLin Jinhan struct rk_hash_ctx *tmp_ctx = (struct rk_hash_ctx *)hw_ctx; 363b353a43cSLin Jinhan u32 reg_ctrl = 0; 364b353a43cSLin Jinhan int ret; 365b353a43cSLin Jinhan 366b353a43cSLin Jinhan if (!tmp_ctx) 367b353a43cSLin Jinhan return -EINVAL; 368b353a43cSLin Jinhan 3691606a214SLin Jinhan reg_ctrl = CRYPTO_SW_CC_RESET; 3701606a214SLin Jinhan crypto_write(reg_ctrl | (reg_ctrl << CRYPTO_WRITE_MASK_SHIFT), 3711606a214SLin Jinhan CRYPTO_RST_CTL); 3721606a214SLin Jinhan 3731606a214SLin Jinhan /* wait reset compelete */ 37449a2135eSLin Jinhan ret = RK_POLL_TIMEOUT(crypto_read(CRYPTO_RST_CTL), 37549a2135eSLin Jinhan RK_CRYPTO_TIMEOUT); 3761606a214SLin Jinhan 3771606a214SLin Jinhan reg_ctrl = 0; 378b353a43cSLin Jinhan tmp_ctx->algo = algo; 379b353a43cSLin Jinhan switch (algo) { 380b353a43cSLin Jinhan case CRYPTO_MD5: 38149a2135eSLin Jinhan case CRYPTO_HMAC_MD5: 382b353a43cSLin Jinhan reg_ctrl |= CRYPTO_MODE_MD5; 383b353a43cSLin Jinhan tmp_ctx->digest_size = 16; 384b353a43cSLin Jinhan break; 385b353a43cSLin Jinhan case CRYPTO_SHA1: 38649a2135eSLin Jinhan case CRYPTO_HMAC_SHA1: 387b353a43cSLin Jinhan reg_ctrl |= CRYPTO_MODE_SHA1; 388b353a43cSLin Jinhan tmp_ctx->digest_size = 20; 389b353a43cSLin Jinhan break; 390b353a43cSLin Jinhan case CRYPTO_SHA256: 39149a2135eSLin Jinhan case CRYPTO_HMAC_SHA256: 392b353a43cSLin Jinhan reg_ctrl |= CRYPTO_MODE_SHA256; 393b353a43cSLin Jinhan tmp_ctx->digest_size = 32; 394b353a43cSLin Jinhan break; 395e7846385SLin Jinhan case CRYPTO_SHA512: 39649a2135eSLin Jinhan case CRYPTO_HMAC_SHA512: 397e7846385SLin Jinhan reg_ctrl |= CRYPTO_MODE_SHA512; 398e7846385SLin Jinhan tmp_ctx->digest_size = 64; 399e7846385SLin Jinhan break; 40049a2135eSLin Jinhan case CRYPTO_SM3: 40149a2135eSLin Jinhan case CRYPTO_HMAC_SM3: 40249a2135eSLin Jinhan reg_ctrl |= CRYPTO_MODE_SM3; 40349a2135eSLin Jinhan tmp_ctx->digest_size = 32; 40449a2135eSLin Jinhan break; 405b353a43cSLin Jinhan default: 406b353a43cSLin Jinhan ret = -EINVAL; 407b353a43cSLin Jinhan goto exit; 408b353a43cSLin Jinhan } 409b353a43cSLin Jinhan 410b353a43cSLin Jinhan /* enable hardware padding */ 411b353a43cSLin Jinhan reg_ctrl |= CRYPTO_HW_PAD_ENABLE; 412b353a43cSLin Jinhan crypto_write(reg_ctrl | CRYPTO_WRITE_MASK_ALL, CRYPTO_HASH_CTL); 413b353a43cSLin Jinhan 414b353a43cSLin Jinhan /* FIFO input and output data byte swap */ 415b353a43cSLin Jinhan /* such as B0, B1, B2, B3 -> B3, B2, B1, B0 */ 416b353a43cSLin Jinhan reg_ctrl = CRYPTO_DOUT_BYTESWAP | CRYPTO_DOIN_BYTESWAP; 417b353a43cSLin Jinhan crypto_write(reg_ctrl | CRYPTO_WRITE_MASK_ALL, CRYPTO_FIFO_CTL); 418b353a43cSLin Jinhan 4191606a214SLin Jinhan /* enable src_item_done interrupt */ 420fe0c4b19SLin Jinhan crypto_write(0, CRYPTO_DMA_INT_EN); 421b353a43cSLin Jinhan 422b353a43cSLin Jinhan tmp_ctx->magic = RK_HASH_CTX_MAGIC; 423b353a43cSLin Jinhan 424b353a43cSLin Jinhan return 0; 425b353a43cSLin Jinhan exit: 426b353a43cSLin Jinhan /* clear hash setting if init failed */ 427b353a43cSLin Jinhan crypto_write(CRYPTO_WRITE_MASK_ALL | 0, CRYPTO_HASH_CTL); 428b353a43cSLin Jinhan 429b353a43cSLin Jinhan return ret; 430b353a43cSLin Jinhan } 431b353a43cSLin Jinhan 432c48f1acfSLin Jinhan static int rk_hash_direct_calc(void *hw_data, const u8 *data, 4331606a214SLin Jinhan u32 data_len, u8 *started_flag, u8 is_last) 434b353a43cSLin Jinhan { 435c48f1acfSLin Jinhan struct rockchip_crypto_priv *priv = hw_data; 436c48f1acfSLin Jinhan struct rk_hash_ctx *hash_ctx = priv->hw_ctx; 437c48f1acfSLin Jinhan struct crypto_lli_desc *lli = &hash_ctx->data_lli; 438b353a43cSLin Jinhan int ret = -EINVAL; 43900fa57d8SLin Jinhan u32 tmp = 0, mask = 0; 440b353a43cSLin Jinhan 44149a2135eSLin Jinhan assert(IS_ALIGNED((ulong)data, DATA_ADDR_ALIGN_SIZE)); 44249a2135eSLin Jinhan assert(is_last || IS_ALIGNED(data_len, DATA_LEN_ALIGN_SIZE)); 443b353a43cSLin Jinhan 4441606a214SLin Jinhan debug("%s: data = %p, len = %u, s = %x, l = %x\n", 4451606a214SLin Jinhan __func__, data, data_len, *started_flag, is_last); 446b353a43cSLin Jinhan 4471606a214SLin Jinhan memset(lli, 0x00, sizeof(*lli)); 4481606a214SLin Jinhan lli->src_addr = (u32)virt_to_phys(data); 4491606a214SLin Jinhan lli->src_len = data_len; 4501606a214SLin Jinhan lli->dma_ctrl = LLI_DMA_CTRL_SRC_DONE; 451b353a43cSLin Jinhan 4521606a214SLin Jinhan if (is_last) { 4531606a214SLin Jinhan lli->user_define |= LLI_USER_STRING_LAST; 4541606a214SLin Jinhan lli->dma_ctrl |= LLI_DMA_CTRL_LAST; 455b353a43cSLin Jinhan } else { 4561606a214SLin Jinhan lli->next_addr = (u32)virt_to_phys(lli); 4571606a214SLin Jinhan lli->dma_ctrl |= LLI_DMA_CTRL_PAUSE; 4581606a214SLin Jinhan } 4591606a214SLin Jinhan 4601606a214SLin Jinhan if (!(*started_flag)) { 4611606a214SLin Jinhan lli->user_define |= 462ce7f4cd6SLin Jinhan (LLI_USER_STRING_START | LLI_USER_CIPHER_START); 4631606a214SLin Jinhan crypto_write((u32)virt_to_phys(lli), CRYPTO_DMA_LLI_ADDR); 4641606a214SLin Jinhan crypto_write((CRYPTO_HASH_ENABLE << CRYPTO_WRITE_MASK_SHIFT) | 4651606a214SLin Jinhan CRYPTO_HASH_ENABLE, CRYPTO_HASH_CTL); 4661606a214SLin Jinhan tmp = CRYPTO_DMA_START; 4671606a214SLin Jinhan *started_flag = 1; 4681606a214SLin Jinhan } else { 469b353a43cSLin Jinhan tmp = CRYPTO_DMA_RESTART; 470b353a43cSLin Jinhan } 471b353a43cSLin Jinhan 472b353a43cSLin Jinhan /* flush cache */ 473c48f1acfSLin Jinhan crypto_flush_cacheline((ulong)lli, sizeof(*lli)); 474c48f1acfSLin Jinhan crypto_flush_cacheline((ulong)data, data_len); 475b353a43cSLin Jinhan 476b353a43cSLin Jinhan /* start calculate */ 477b353a43cSLin Jinhan crypto_write(tmp << CRYPTO_WRITE_MASK_SHIFT | tmp, 478b353a43cSLin Jinhan CRYPTO_DMA_CTL); 479b353a43cSLin Jinhan 48000fa57d8SLin Jinhan /* mask CRYPTO_SYNC_LOCKSTEP_INT_ST flag */ 48100fa57d8SLin Jinhan mask = ~(mask | CRYPTO_SYNC_LOCKSTEP_INT_ST); 48200fa57d8SLin Jinhan 483b353a43cSLin Jinhan /* wait calc ok */ 48449a2135eSLin Jinhan ret = RK_POLL_TIMEOUT(!(crypto_read(CRYPTO_DMA_INT_ST) & mask), 48549a2135eSLin Jinhan RK_CRYPTO_TIMEOUT); 486b353a43cSLin Jinhan 487b353a43cSLin Jinhan /* clear interrupt status */ 488b353a43cSLin Jinhan tmp = crypto_read(CRYPTO_DMA_INT_ST); 489b353a43cSLin Jinhan crypto_write(tmp, CRYPTO_DMA_INT_ST); 490b353a43cSLin Jinhan 49149cbb0faSLin Jinhan if ((tmp & mask) != CRYPTO_SRC_ITEM_DONE_INT_ST && 49249cbb0faSLin Jinhan (tmp & mask) != CRYPTO_ZERO_LEN_INT_ST) { 49346aac970SLin Jinhan ret = -EFAULT; 4941606a214SLin Jinhan debug("[%s] %d: CRYPTO_DMA_INT_ST = 0x%x\n", 495b353a43cSLin Jinhan __func__, __LINE__, tmp); 4961606a214SLin Jinhan goto exit; 497b353a43cSLin Jinhan } 498b353a43cSLin Jinhan 499c48f1acfSLin Jinhan priv->length += data_len; 5001606a214SLin Jinhan exit: 5011606a214SLin Jinhan return ret; 502b353a43cSLin Jinhan } 5031606a214SLin Jinhan 5041606a214SLin Jinhan int rk_hash_update(void *ctx, const u8 *data, u32 data_len) 5051606a214SLin Jinhan { 5061606a214SLin Jinhan struct rk_hash_ctx *tmp_ctx = (struct rk_hash_ctx *)ctx; 507c48f1acfSLin Jinhan int ret = -EINVAL; 5081606a214SLin Jinhan 5091606a214SLin Jinhan debug("\n"); 5101606a214SLin Jinhan if (!tmp_ctx || !data) 511c48f1acfSLin Jinhan goto exit; 5121606a214SLin Jinhan 5131606a214SLin Jinhan if (tmp_ctx->digest_size == 0 || tmp_ctx->magic != RK_HASH_CTX_MAGIC) 514c48f1acfSLin Jinhan goto exit; 5151606a214SLin Jinhan 516c48f1acfSLin Jinhan ret = crypto_hash_update_with_cache(tmp_ctx->hash_cache, 517c48f1acfSLin Jinhan data, data_len); 5181606a214SLin Jinhan 519c48f1acfSLin Jinhan exit: 520b353a43cSLin Jinhan /* free lli list */ 521c48f1acfSLin Jinhan if (ret) 522b353a43cSLin Jinhan hw_hash_clean_ctx(tmp_ctx); 523b353a43cSLin Jinhan 524c48f1acfSLin Jinhan return ret; 525b353a43cSLin Jinhan } 526b353a43cSLin Jinhan 527b353a43cSLin Jinhan int rk_hash_final(void *ctx, u8 *digest, size_t len) 528b353a43cSLin Jinhan { 529b353a43cSLin Jinhan struct rk_hash_ctx *tmp_ctx = (struct rk_hash_ctx *)ctx; 530e0c259feSLin Jinhan int ret = 0; 531b353a43cSLin Jinhan 532b353a43cSLin Jinhan if (!digest) 533b353a43cSLin Jinhan goto exit; 534b353a43cSLin Jinhan 535b353a43cSLin Jinhan if (!tmp_ctx || 536b353a43cSLin Jinhan tmp_ctx->digest_size == 0 || 537b353a43cSLin Jinhan len > tmp_ctx->digest_size || 538b353a43cSLin Jinhan tmp_ctx->magic != RK_HASH_CTX_MAGIC) { 539b353a43cSLin Jinhan goto exit; 540b353a43cSLin Jinhan } 541b353a43cSLin Jinhan 542e0c259feSLin Jinhan if(is_check_hash_valid()) { 543b353a43cSLin Jinhan /* wait hash value ok */ 54449a2135eSLin Jinhan ret = RK_POLL_TIMEOUT(!crypto_read(CRYPTO_HASH_VALID), 54549a2135eSLin Jinhan RK_CRYPTO_TIMEOUT); 546e0c259feSLin Jinhan } 547b353a43cSLin Jinhan 548c3ce9937SLin Jinhan read_regs(CRYPTO_HASH_DOUT_0, digest, len); 549b353a43cSLin Jinhan 550b353a43cSLin Jinhan /* clear hash status */ 551b353a43cSLin Jinhan crypto_write(CRYPTO_HASH_IS_VALID, CRYPTO_HASH_VALID); 552b353a43cSLin Jinhan crypto_write(CRYPTO_WRITE_MASK_ALL | 0, CRYPTO_HASH_CTL); 553b353a43cSLin Jinhan 554b353a43cSLin Jinhan exit: 555b353a43cSLin Jinhan 556b353a43cSLin Jinhan return ret; 557b353a43cSLin Jinhan } 558b353a43cSLin Jinhan 559b353a43cSLin Jinhan static u32 rockchip_crypto_capability(struct udevice *dev) 560b353a43cSLin Jinhan { 56149a2135eSLin Jinhan struct rockchip_crypto_priv *priv = dev_get_priv(dev); 56249a2135eSLin Jinhan u32 capability, mask = 0; 5637eea1823SLin Jinhan 56449a2135eSLin Jinhan capability = priv->soc_data->capability; 56549a2135eSLin Jinhan 56649a2135eSLin Jinhan #if !(CONFIG_IS_ENABLED(ROCKCHIP_CIPHER)) 56749a2135eSLin Jinhan mask |= (CRYPTO_DES | CRYPTO_AES | CRYPTO_SM4); 568c0e47d03SLin Jinhan #endif 5697eea1823SLin Jinhan 57049a2135eSLin Jinhan #if !(CONFIG_IS_ENABLED(ROCKCHIP_HMAC)) 57149a2135eSLin Jinhan mask |= (CRYPTO_HMAC_MD5 | CRYPTO_HMAC_SHA1 | CRYPTO_HMAC_SHA256 | 57249a2135eSLin Jinhan CRYPTO_HMAC_SHA512 | CRYPTO_HMAC_SM3); 57349a2135eSLin Jinhan #endif 57449a2135eSLin Jinhan 57549a2135eSLin Jinhan #if !(CONFIG_IS_ENABLED(ROCKCHIP_RSA)) 57649a2135eSLin Jinhan mask |= (CRYPTO_RSA512 | CRYPTO_RSA1024 | CRYPTO_RSA2048 | 57749a2135eSLin Jinhan CRYPTO_RSA3072 | CRYPTO_RSA4096); 57849a2135eSLin Jinhan #endif 57949a2135eSLin Jinhan 58049a2135eSLin Jinhan return capability & (~mask); 581b353a43cSLin Jinhan } 582b353a43cSLin Jinhan 583b353a43cSLin Jinhan static int rockchip_crypto_sha_init(struct udevice *dev, sha_context *ctx) 584b353a43cSLin Jinhan { 585b353a43cSLin Jinhan struct rockchip_crypto_priv *priv = dev_get_priv(dev); 586c48f1acfSLin Jinhan struct rk_hash_ctx *hash_ctx = priv->hw_ctx; 587dd7763a8SFinley Xiao int ret = 0; 588b353a43cSLin Jinhan 589b353a43cSLin Jinhan if (!ctx) 590b353a43cSLin Jinhan return -EINVAL; 591b353a43cSLin Jinhan 592c48f1acfSLin Jinhan memset(hash_ctx, 0x00, sizeof(*hash_ctx)); 593b353a43cSLin Jinhan 594c48f1acfSLin Jinhan priv->length = 0; 595c48f1acfSLin Jinhan 596c48f1acfSLin Jinhan hash_ctx->hash_cache = crypto_hash_cache_alloc(rk_hash_direct_calc, 597c48f1acfSLin Jinhan priv, ctx->length, 59849a2135eSLin Jinhan DATA_ADDR_ALIGN_SIZE, 59949a2135eSLin Jinhan DATA_LEN_ALIGN_SIZE); 600c48f1acfSLin Jinhan if (!hash_ctx->hash_cache) 601c48f1acfSLin Jinhan return -EFAULT; 602c48f1acfSLin Jinhan 603dd7763a8SFinley Xiao rk_crypto_enable_clk(dev); 604dd7763a8SFinley Xiao ret = rk_hash_init(hash_ctx, ctx->algo); 605dd7763a8SFinley Xiao if (ret) 606dd7763a8SFinley Xiao rk_crypto_disable_clk(dev); 607dd7763a8SFinley Xiao 608dd7763a8SFinley Xiao return ret; 609b353a43cSLin Jinhan } 610b353a43cSLin Jinhan 611b353a43cSLin Jinhan static int rockchip_crypto_sha_update(struct udevice *dev, 612b353a43cSLin Jinhan u32 *input, u32 len) 613b353a43cSLin Jinhan { 614b353a43cSLin Jinhan struct rockchip_crypto_priv *priv = dev_get_priv(dev); 615086e8fa8SLin Jinhan int ret, i; 616086e8fa8SLin Jinhan u8 *p; 617b353a43cSLin Jinhan 618dd7763a8SFinley Xiao if (!len) { 619dd7763a8SFinley Xiao ret = -EINVAL; 620dd7763a8SFinley Xiao goto exit; 621dd7763a8SFinley Xiao } 622b353a43cSLin Jinhan 623086e8fa8SLin Jinhan p = (u8 *)input; 624086e8fa8SLin Jinhan 625086e8fa8SLin Jinhan for (i = 0; i < len / HASH_UPDATE_LIMIT; i++, p += HASH_UPDATE_LIMIT) { 626086e8fa8SLin Jinhan ret = rk_hash_update(priv->hw_ctx, p, HASH_UPDATE_LIMIT); 627086e8fa8SLin Jinhan if (ret) 628086e8fa8SLin Jinhan goto exit; 629086e8fa8SLin Jinhan } 630086e8fa8SLin Jinhan 631086e8fa8SLin Jinhan if (len % HASH_UPDATE_LIMIT) 632086e8fa8SLin Jinhan ret = rk_hash_update(priv->hw_ctx, p, len % HASH_UPDATE_LIMIT); 633086e8fa8SLin Jinhan 634086e8fa8SLin Jinhan exit: 635dd7763a8SFinley Xiao if (ret) 636dd7763a8SFinley Xiao rk_crypto_disable_clk(dev); 637dd7763a8SFinley Xiao 638086e8fa8SLin Jinhan return ret; 639b353a43cSLin Jinhan } 640b353a43cSLin Jinhan 641b353a43cSLin Jinhan static int rockchip_crypto_sha_final(struct udevice *dev, 642b353a43cSLin Jinhan sha_context *ctx, u8 *output) 643b353a43cSLin Jinhan { 644b353a43cSLin Jinhan struct rockchip_crypto_priv *priv = dev_get_priv(dev); 645b353a43cSLin Jinhan u32 nbits; 646c48f1acfSLin Jinhan int ret; 647b353a43cSLin Jinhan 648b353a43cSLin Jinhan nbits = crypto_algo_nbits(ctx->algo); 649b353a43cSLin Jinhan 650c48f1acfSLin Jinhan if (priv->length != ctx->length) { 651c48f1acfSLin Jinhan printf("total length(0x%08x) != init length(0x%08x)!\n", 652c48f1acfSLin Jinhan priv->length, ctx->length); 653c48f1acfSLin Jinhan ret = -EIO; 654c48f1acfSLin Jinhan goto exit; 655c48f1acfSLin Jinhan } 656c48f1acfSLin Jinhan 657c48f1acfSLin Jinhan ret = rk_hash_final(priv->hw_ctx, (u8 *)output, BITS2BYTE(nbits)); 658c48f1acfSLin Jinhan 659c48f1acfSLin Jinhan exit: 660c48f1acfSLin Jinhan hw_hash_clean_ctx(priv->hw_ctx); 661dd7763a8SFinley Xiao rk_crypto_disable_clk(dev); 662dd7763a8SFinley Xiao 663c48f1acfSLin Jinhan return ret; 664b353a43cSLin Jinhan } 665b353a43cSLin Jinhan 66649a2135eSLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_HMAC) 66749a2135eSLin Jinhan int rk_hmac_init(void *hw_ctx, u32 algo, u8 *key, u32 key_len) 66849a2135eSLin Jinhan { 66949a2135eSLin Jinhan u32 reg_ctrl = 0; 67049a2135eSLin Jinhan int ret; 67149a2135eSLin Jinhan 67249a2135eSLin Jinhan if (!key || !key_len || key_len > 64) 67349a2135eSLin Jinhan return -EINVAL; 67449a2135eSLin Jinhan 67549a2135eSLin Jinhan clear_key_regs(); 67649a2135eSLin Jinhan 67749a2135eSLin Jinhan write_key_reg(0, key, key_len); 67849a2135eSLin Jinhan 67949a2135eSLin Jinhan ret = rk_hash_init(hw_ctx, algo); 68049a2135eSLin Jinhan if (ret) 68149a2135eSLin Jinhan return ret; 68249a2135eSLin Jinhan 68349a2135eSLin Jinhan reg_ctrl = crypto_read(CRYPTO_HASH_CTL) | CRYPTO_HMAC_ENABLE; 68449a2135eSLin Jinhan crypto_write(reg_ctrl | CRYPTO_WRITE_MASK_ALL, CRYPTO_HASH_CTL); 68549a2135eSLin Jinhan 68649a2135eSLin Jinhan return ret; 68749a2135eSLin Jinhan } 68849a2135eSLin Jinhan 68949a2135eSLin Jinhan static int rockchip_crypto_hmac_init(struct udevice *dev, 69049a2135eSLin Jinhan sha_context *ctx, u8 *key, u32 key_len) 69149a2135eSLin Jinhan { 69249a2135eSLin Jinhan struct rockchip_crypto_priv *priv = dev_get_priv(dev); 69349a2135eSLin Jinhan struct rk_hash_ctx *hash_ctx = priv->hw_ctx; 694dd7763a8SFinley Xiao int ret = 0; 69549a2135eSLin Jinhan 69649a2135eSLin Jinhan if (!ctx) 69749a2135eSLin Jinhan return -EINVAL; 69849a2135eSLin Jinhan 69949a2135eSLin Jinhan memset(hash_ctx, 0x00, sizeof(*hash_ctx)); 70049a2135eSLin Jinhan 70149a2135eSLin Jinhan priv->length = 0; 70249a2135eSLin Jinhan 70349a2135eSLin Jinhan hash_ctx->hash_cache = crypto_hash_cache_alloc(rk_hash_direct_calc, 70449a2135eSLin Jinhan priv, ctx->length, 70549a2135eSLin Jinhan DATA_ADDR_ALIGN_SIZE, 70649a2135eSLin Jinhan DATA_LEN_ALIGN_SIZE); 70749a2135eSLin Jinhan if (!hash_ctx->hash_cache) 70849a2135eSLin Jinhan return -EFAULT; 70949a2135eSLin Jinhan 710dd7763a8SFinley Xiao rk_crypto_enable_clk(dev); 711dd7763a8SFinley Xiao ret = rk_hmac_init(priv->hw_ctx, ctx->algo, key, key_len); 712dd7763a8SFinley Xiao if (ret) 713dd7763a8SFinley Xiao rk_crypto_disable_clk(dev); 714dd7763a8SFinley Xiao 715dd7763a8SFinley Xiao return ret; 71649a2135eSLin Jinhan } 71749a2135eSLin Jinhan 71849a2135eSLin Jinhan static int rockchip_crypto_hmac_update(struct udevice *dev, 71949a2135eSLin Jinhan u32 *input, u32 len) 72049a2135eSLin Jinhan { 72149a2135eSLin Jinhan return rockchip_crypto_sha_update(dev, input, len); 72249a2135eSLin Jinhan } 72349a2135eSLin Jinhan 72449a2135eSLin Jinhan static int rockchip_crypto_hmac_final(struct udevice *dev, 72549a2135eSLin Jinhan sha_context *ctx, u8 *output) 72649a2135eSLin Jinhan { 72749a2135eSLin Jinhan return rockchip_crypto_sha_final(dev, ctx, output); 72849a2135eSLin Jinhan } 72949a2135eSLin Jinhan 73049a2135eSLin Jinhan #endif 73149a2135eSLin Jinhan 73249a2135eSLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_CIPHER) 73349a2135eSLin Jinhan static u8 g_key_chn; 73449a2135eSLin Jinhan 73549a2135eSLin Jinhan static const u32 rk_mode2bc_mode[RK_MODE_MAX] = { 73649a2135eSLin Jinhan [RK_MODE_ECB] = CRYPTO_BC_ECB, 73749a2135eSLin Jinhan [RK_MODE_CBC] = CRYPTO_BC_CBC, 73849a2135eSLin Jinhan [RK_MODE_CTS] = CRYPTO_BC_CTS, 73949a2135eSLin Jinhan [RK_MODE_CTR] = CRYPTO_BC_CTR, 74049a2135eSLin Jinhan [RK_MODE_CFB] = CRYPTO_BC_CFB, 74149a2135eSLin Jinhan [RK_MODE_OFB] = CRYPTO_BC_OFB, 74249a2135eSLin Jinhan [RK_MODE_XTS] = CRYPTO_BC_XTS, 743c3ce9937SLin Jinhan [RK_MODE_CCM] = CRYPTO_BC_CCM, 744c3ce9937SLin Jinhan [RK_MODE_GCM] = CRYPTO_BC_GCM, 745d9332f1cSLin Jinhan [RK_MODE_CMAC] = CRYPTO_BC_CMAC, 746d9332f1cSLin Jinhan [RK_MODE_CBC_MAC] = CRYPTO_BC_CBC_MAC, 74749a2135eSLin Jinhan }; 74849a2135eSLin Jinhan 749c3ce9937SLin Jinhan static inline void set_pc_len_reg(u32 chn, u64 pc_len) 750c3ce9937SLin Jinhan { 751c3ce9937SLin Jinhan u32 chn_base = CRYPTO_CH0_PC_LEN_0 + chn * 0x08; 752c3ce9937SLin Jinhan 753c3ce9937SLin Jinhan crypto_write(pc_len & 0xffffffff, chn_base); 754c3ce9937SLin Jinhan crypto_write(pc_len >> 32, chn_base + 4); 755c3ce9937SLin Jinhan } 756c3ce9937SLin Jinhan 757c3ce9937SLin Jinhan static inline void set_aad_len_reg(u32 chn, u64 pc_len) 758c3ce9937SLin Jinhan { 759c3ce9937SLin Jinhan u32 chn_base = CRYPTO_CH0_AAD_LEN_0 + chn * 0x08; 760c3ce9937SLin Jinhan 761c3ce9937SLin Jinhan crypto_write(pc_len & 0xffffffff, chn_base); 762c3ce9937SLin Jinhan crypto_write(pc_len >> 32, chn_base + 4); 763c3ce9937SLin Jinhan } 764c3ce9937SLin Jinhan 76549a2135eSLin Jinhan static inline bool is_des_mode(u32 rk_mode) 76649a2135eSLin Jinhan { 76749a2135eSLin Jinhan return (rk_mode == RK_MODE_ECB || 76849a2135eSLin Jinhan rk_mode == RK_MODE_CBC || 76949a2135eSLin Jinhan rk_mode == RK_MODE_CFB || 77049a2135eSLin Jinhan rk_mode == RK_MODE_OFB); 77149a2135eSLin Jinhan } 77249a2135eSLin Jinhan 7736b53126aSLin Jinhan static void dump_crypto_state(struct crypto_lli_desc *desc, 7746b53126aSLin Jinhan u32 tmp, u32 expt_int, 7756b53126aSLin Jinhan const u8 *in, const u8 *out, 7766b53126aSLin Jinhan u32 len, int ret) 77749a2135eSLin Jinhan { 77849a2135eSLin Jinhan IMSG("%s\n", ret == -ETIME ? "timeout" : "dismatch"); 77949a2135eSLin Jinhan 78049a2135eSLin Jinhan IMSG("CRYPTO_DMA_INT_ST = %08x, expect_int = %08x\n", 78149a2135eSLin Jinhan tmp, expt_int); 78249a2135eSLin Jinhan IMSG("data desc = %p\n", desc); 78349a2135eSLin Jinhan IMSG("\taddr_in = [%08x <=> %08x]\n", 78449a2135eSLin Jinhan desc->src_addr, (u32)virt_to_phys(in)); 78549a2135eSLin Jinhan IMSG("\taddr_out = [%08x <=> %08x]\n", 78649a2135eSLin Jinhan desc->dst_addr, (u32)virt_to_phys(out)); 78749a2135eSLin Jinhan IMSG("\tsrc_len = [%08x <=> %08x]\n", 78849a2135eSLin Jinhan desc->src_len, (u32)len); 78949a2135eSLin Jinhan IMSG("\tdst_len = %08x\n", desc->dst_len); 79049a2135eSLin Jinhan IMSG("\tdma_ctl = %08x\n", desc->dma_ctrl); 79149a2135eSLin Jinhan IMSG("\tuser_define = %08x\n", desc->user_define); 79249a2135eSLin Jinhan 79349a2135eSLin Jinhan IMSG("\n\nDMA CRYPTO_DMA_LLI_ADDR status = %08x\n", 79449a2135eSLin Jinhan crypto_read(CRYPTO_DMA_LLI_ADDR)); 79549a2135eSLin Jinhan IMSG("DMA CRYPTO_DMA_ST status = %08x\n", 79649a2135eSLin Jinhan crypto_read(CRYPTO_DMA_ST)); 79749a2135eSLin Jinhan IMSG("DMA CRYPTO_DMA_STATE status = %08x\n", 79849a2135eSLin Jinhan crypto_read(CRYPTO_DMA_STATE)); 79949a2135eSLin Jinhan IMSG("DMA CRYPTO_DMA_LLI_RADDR status = %08x\n", 80049a2135eSLin Jinhan crypto_read(CRYPTO_DMA_LLI_RADDR)); 80149a2135eSLin Jinhan IMSG("DMA CRYPTO_DMA_SRC_RADDR status = %08x\n", 80249a2135eSLin Jinhan crypto_read(CRYPTO_DMA_SRC_RADDR)); 80349a2135eSLin Jinhan IMSG("DMA CRYPTO_DMA_DST_RADDR status = %08x\n", 80449a2135eSLin Jinhan crypto_read(CRYPTO_DMA_DST_RADDR)); 80549a2135eSLin Jinhan IMSG("DMA CRYPTO_CIPHER_ST status = %08x\n", 80649a2135eSLin Jinhan crypto_read(CRYPTO_CIPHER_ST)); 80749a2135eSLin Jinhan IMSG("DMA CRYPTO_CIPHER_STATE status = %08x\n", 80849a2135eSLin Jinhan crypto_read(CRYPTO_CIPHER_STATE)); 80949a2135eSLin Jinhan IMSG("DMA CRYPTO_TAG_VALID status = %08x\n", 81049a2135eSLin Jinhan crypto_read(CRYPTO_TAG_VALID)); 81149a2135eSLin Jinhan IMSG("LOCKSTEP status = %08x\n\n", 81249a2135eSLin Jinhan crypto_read(0x618)); 81349a2135eSLin Jinhan 81449a2135eSLin Jinhan IMSG("dst %dbyte not transferred\n", 81549a2135eSLin Jinhan desc->dst_addr + desc->dst_len - 81649a2135eSLin Jinhan crypto_read(CRYPTO_DMA_DST_RADDR)); 81749a2135eSLin Jinhan } 81849a2135eSLin Jinhan 819c3ce9937SLin Jinhan static int ccm128_set_iv_reg(u32 chn, const u8 *nonce, u32 nlen) 820c3ce9937SLin Jinhan { 821c3ce9937SLin Jinhan u8 iv_buf[AES_BLOCK_SIZE]; 822c3ce9937SLin Jinhan u32 L; 823c3ce9937SLin Jinhan 824c3ce9937SLin Jinhan memset(iv_buf, 0x00, sizeof(iv_buf)); 825c3ce9937SLin Jinhan 826c3ce9937SLin Jinhan L = 15 - nlen; 827c3ce9937SLin Jinhan iv_buf[0] = ((u8)(L - 1) & 7); 828c3ce9937SLin Jinhan 829c3ce9937SLin Jinhan /* the L parameter */ 830c3ce9937SLin Jinhan L = iv_buf[0] & 7; 831c3ce9937SLin Jinhan 832c3ce9937SLin Jinhan /* nonce is too short */ 833c3ce9937SLin Jinhan if (nlen < (14 - L)) 834c3ce9937SLin Jinhan return -EINVAL; 835c3ce9937SLin Jinhan 836c3ce9937SLin Jinhan /* clear aad flag */ 837c3ce9937SLin Jinhan iv_buf[0] &= ~0x40; 838c3ce9937SLin Jinhan memcpy(&iv_buf[1], nonce, 14 - L); 839c3ce9937SLin Jinhan 840c3ce9937SLin Jinhan set_iv_reg(chn, iv_buf, AES_BLOCK_SIZE); 841c3ce9937SLin Jinhan 842c3ce9937SLin Jinhan return 0; 843c3ce9937SLin Jinhan } 844c3ce9937SLin Jinhan 845c3ce9937SLin Jinhan static void ccm_aad_padding(u32 aad_len, u8 *padding, u32 *padding_size) 846c3ce9937SLin Jinhan { 847c3ce9937SLin Jinhan u32 i; 848c3ce9937SLin Jinhan 8492db770efSLin Jinhan if (aad_len == 0) { 8502db770efSLin Jinhan *padding_size = 0; 8512db770efSLin Jinhan return; 8522db770efSLin Jinhan } 8532db770efSLin Jinhan 854c3ce9937SLin Jinhan i = aad_len < (0x10000 - 0x100) ? 2 : 6; 855c3ce9937SLin Jinhan 856c3ce9937SLin Jinhan if (i == 2) { 857c3ce9937SLin Jinhan padding[0] = (u8)(aad_len >> 8); 858c3ce9937SLin Jinhan padding[1] = (u8)aad_len; 859c3ce9937SLin Jinhan } else { 860c3ce9937SLin Jinhan padding[0] = 0xFF; 861c3ce9937SLin Jinhan padding[1] = 0xFE; 862c3ce9937SLin Jinhan padding[2] = (u8)(aad_len >> 24); 863c3ce9937SLin Jinhan padding[3] = (u8)(aad_len >> 16); 864c3ce9937SLin Jinhan padding[4] = (u8)(aad_len >> 8); 865c3ce9937SLin Jinhan } 866c3ce9937SLin Jinhan 867c3ce9937SLin Jinhan *padding_size = i; 868c3ce9937SLin Jinhan } 869c3ce9937SLin Jinhan 8702db770efSLin Jinhan static int ccm_compose_aad_iv(u8 *aad_iv, u32 data_len, u32 aad_len, u32 tag_size) 871c3ce9937SLin Jinhan { 872c3ce9937SLin Jinhan aad_iv[0] |= ((u8)(((tag_size - 2) / 2) & 7) << 3); 873c3ce9937SLin Jinhan 874c3ce9937SLin Jinhan aad_iv[12] = (u8)(data_len >> 24); 875c3ce9937SLin Jinhan aad_iv[13] = (u8)(data_len >> 16); 876c3ce9937SLin Jinhan aad_iv[14] = (u8)(data_len >> 8); 877c3ce9937SLin Jinhan aad_iv[15] = (u8)data_len; 878c3ce9937SLin Jinhan 8792db770efSLin Jinhan if (aad_len) 880c3ce9937SLin Jinhan aad_iv[0] |= 0x40; //set aad flag 881c3ce9937SLin Jinhan 882c3ce9937SLin Jinhan return 0; 883c3ce9937SLin Jinhan } 884c3ce9937SLin Jinhan 88549a2135eSLin Jinhan static int hw_cipher_init(u32 chn, const u8 *key, const u8 *twk_key, 88649a2135eSLin Jinhan u32 key_len, const u8 *iv, u32 iv_len, 88749a2135eSLin Jinhan u32 algo, u32 mode, bool enc) 88849a2135eSLin Jinhan { 88949a2135eSLin Jinhan u32 rk_mode = RK_GET_RK_MODE(mode); 89049a2135eSLin Jinhan u32 key_chn_sel = chn; 89149a2135eSLin Jinhan u32 reg_ctrl = 0; 892*eecb3765SLin Jinhan bool use_otpkey = false; 893*eecb3765SLin Jinhan 894*eecb3765SLin Jinhan if (!key && key_len) 895*eecb3765SLin Jinhan use_otpkey = true; 89649a2135eSLin Jinhan 89749a2135eSLin Jinhan IMSG("%s: key addr is %p, key_len is %d, iv addr is %p", 89849a2135eSLin Jinhan __func__, key, key_len, iv); 89949a2135eSLin Jinhan if (rk_mode >= RK_MODE_MAX) 90049a2135eSLin Jinhan return -EINVAL; 90149a2135eSLin Jinhan 90249a2135eSLin Jinhan switch (algo) { 90349a2135eSLin Jinhan case CRYPTO_DES: 90449a2135eSLin Jinhan if (key_len > DES_BLOCK_SIZE) 90549a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_TDES; 90649a2135eSLin Jinhan else 90749a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_DES; 90849a2135eSLin Jinhan break; 90949a2135eSLin Jinhan case CRYPTO_AES: 91049a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_AES; 91149a2135eSLin Jinhan break; 91249a2135eSLin Jinhan case CRYPTO_SM4: 91349a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_SM4; 91449a2135eSLin Jinhan break; 91549a2135eSLin Jinhan default: 91649a2135eSLin Jinhan return -EINVAL; 91749a2135eSLin Jinhan } 91849a2135eSLin Jinhan 91949a2135eSLin Jinhan if (algo == CRYPTO_AES || algo == CRYPTO_SM4) { 92049a2135eSLin Jinhan switch (key_len) { 92149a2135eSLin Jinhan case AES_KEYSIZE_128: 92249a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_128_bit_key; 92349a2135eSLin Jinhan break; 92449a2135eSLin Jinhan case AES_KEYSIZE_192: 92549a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_192_bit_key; 92649a2135eSLin Jinhan break; 92749a2135eSLin Jinhan case AES_KEYSIZE_256: 92849a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_256_bit_key; 92949a2135eSLin Jinhan break; 93049a2135eSLin Jinhan default: 93149a2135eSLin Jinhan return -EINVAL; 93249a2135eSLin Jinhan } 93349a2135eSLin Jinhan } 93449a2135eSLin Jinhan 93549a2135eSLin Jinhan reg_ctrl |= rk_mode2bc_mode[rk_mode]; 93649a2135eSLin Jinhan if (!enc) 93749a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_DECRYPT; 93849a2135eSLin Jinhan 93949a2135eSLin Jinhan /* write key data to reg */ 940*eecb3765SLin Jinhan if (!use_otpkey) { 94149a2135eSLin Jinhan write_key_reg(key_chn_sel, key, key_len); 942*eecb3765SLin Jinhan crypto_write(CRYPTO_SEL_USER, CRYPTO_KEY_SEL); 943*eecb3765SLin Jinhan } else { 944*eecb3765SLin Jinhan crypto_write(CRYPTO_SEL_KEYTABLE, CRYPTO_KEY_SEL); 945*eecb3765SLin Jinhan } 94649a2135eSLin Jinhan 94749a2135eSLin Jinhan /* write twk key for xts mode */ 94849a2135eSLin Jinhan if (rk_mode == RK_MODE_XTS) 94949a2135eSLin Jinhan write_key_reg(key_chn_sel + 4, twk_key, key_len); 95049a2135eSLin Jinhan 95149a2135eSLin Jinhan /* set iv reg */ 952c3ce9937SLin Jinhan if (rk_mode == RK_MODE_CCM) 953c3ce9937SLin Jinhan ccm128_set_iv_reg(chn, iv, iv_len); 954c3ce9937SLin Jinhan else 95549a2135eSLin Jinhan set_iv_reg(chn, iv, iv_len); 95649a2135eSLin Jinhan 95749a2135eSLin Jinhan /* din_swap set 1, dout_swap set 1, default 1. */ 95849a2135eSLin Jinhan crypto_write(0x00030003, CRYPTO_FIFO_CTL); 959fe0c4b19SLin Jinhan crypto_write(0, CRYPTO_DMA_INT_EN); 96049a2135eSLin Jinhan 96149a2135eSLin Jinhan crypto_write(reg_ctrl | CRYPTO_WRITE_MASK_ALL, CRYPTO_BC_CTL); 96249a2135eSLin Jinhan 96349a2135eSLin Jinhan return 0; 96449a2135eSLin Jinhan } 96549a2135eSLin Jinhan 96649a2135eSLin Jinhan static int hw_cipher_crypt(const u8 *in, u8 *out, u64 len, 967c3ce9937SLin Jinhan const u8 *aad, u32 aad_len, 968c3ce9937SLin Jinhan u8 *tag, u32 tag_len, u32 mode) 96949a2135eSLin Jinhan { 970c3ce9937SLin Jinhan struct crypto_lli_desc *data_desc = NULL, *aad_desc = NULL; 971c3ce9937SLin Jinhan u8 *dma_in = NULL, *dma_out = NULL, *aad_tmp = NULL; 97249a2135eSLin Jinhan u32 rk_mode = RK_GET_RK_MODE(mode); 97349a2135eSLin Jinhan u32 reg_ctrl = 0, tmp_len = 0; 97449a2135eSLin Jinhan u32 expt_int = 0, mask = 0; 97549a2135eSLin Jinhan u32 key_chn = g_key_chn; 97649a2135eSLin Jinhan u32 tmp, dst_len = 0; 97749a2135eSLin Jinhan int ret = -1; 97849a2135eSLin Jinhan 97949a2135eSLin Jinhan if (rk_mode == RK_MODE_CTS && len <= AES_BLOCK_SIZE) { 98049a2135eSLin Jinhan printf("CTS mode length %u < 16Byte\n", (u32)len); 98149a2135eSLin Jinhan return -EINVAL; 98249a2135eSLin Jinhan } 98349a2135eSLin Jinhan 98449a2135eSLin Jinhan tmp_len = (rk_mode == RK_MODE_CTR) ? ROUNDUP(len, AES_BLOCK_SIZE) : len; 98549a2135eSLin Jinhan 98649a2135eSLin Jinhan data_desc = align_malloc(sizeof(*data_desc), LLI_ADDR_ALIGN_SIZE); 98749a2135eSLin Jinhan if (!data_desc) 98849a2135eSLin Jinhan goto exit; 98949a2135eSLin Jinhan 99049a2135eSLin Jinhan if (IS_ALIGNED((ulong)in, DATA_ADDR_ALIGN_SIZE) && tmp_len == len) 99149a2135eSLin Jinhan dma_in = (void *)in; 99249a2135eSLin Jinhan else 99349a2135eSLin Jinhan dma_in = align_malloc(tmp_len, DATA_ADDR_ALIGN_SIZE); 99449a2135eSLin Jinhan if (!dma_in) 99549a2135eSLin Jinhan goto exit; 99649a2135eSLin Jinhan 99749a2135eSLin Jinhan if (out) { 99849a2135eSLin Jinhan if (IS_ALIGNED((ulong)out, DATA_ADDR_ALIGN_SIZE) && 99949a2135eSLin Jinhan tmp_len == len) 100049a2135eSLin Jinhan dma_out = out; 100149a2135eSLin Jinhan else 100249a2135eSLin Jinhan dma_out = align_malloc(tmp_len, DATA_ADDR_ALIGN_SIZE); 100349a2135eSLin Jinhan if (!dma_out) 100449a2135eSLin Jinhan goto exit; 100549a2135eSLin Jinhan dst_len = tmp_len; 100649a2135eSLin Jinhan } 100749a2135eSLin Jinhan 100849a2135eSLin Jinhan memset(data_desc, 0x00, sizeof(*data_desc)); 100949a2135eSLin Jinhan if (dma_in != in) 101049a2135eSLin Jinhan memcpy(dma_in, in, len); 101149a2135eSLin Jinhan 101249a2135eSLin Jinhan data_desc->src_addr = (u32)virt_to_phys(dma_in); 101349a2135eSLin Jinhan data_desc->src_len = tmp_len; 101449a2135eSLin Jinhan data_desc->dst_addr = (u32)virt_to_phys(dma_out); 101549a2135eSLin Jinhan data_desc->dst_len = dst_len; 1016d9332f1cSLin Jinhan data_desc->dma_ctrl = LLI_DMA_CTRL_LAST; 1017d9332f1cSLin Jinhan 1018d9332f1cSLin Jinhan if (IS_MAC_MODE(rk_mode)) { 1019d9332f1cSLin Jinhan expt_int = CRYPTO_LIST_DONE_INT_ST; 1020d9332f1cSLin Jinhan data_desc->dma_ctrl |= LLI_DMA_CTRL_LIST_DONE; 1021d9332f1cSLin Jinhan } else { 102249a2135eSLin Jinhan expt_int = CRYPTO_DST_ITEM_DONE_INT_ST; 1023d9332f1cSLin Jinhan data_desc->dma_ctrl |= LLI_DMA_CTRL_DST_DONE; 1024d9332f1cSLin Jinhan } 102549a2135eSLin Jinhan 1026ce7f4cd6SLin Jinhan data_desc->user_define = LLI_USER_CIPHER_START | 1027afdbec36SLin Jinhan LLI_USER_STRING_START | 1028c3ce9937SLin Jinhan LLI_USER_STRING_LAST | 1029c3ce9937SLin Jinhan (key_chn << 4); 1030afdbec36SLin Jinhan crypto_write((u32)virt_to_phys(data_desc), CRYPTO_DMA_LLI_ADDR); 1031afdbec36SLin Jinhan 1032afdbec36SLin Jinhan if (rk_mode == RK_MODE_CCM || rk_mode == RK_MODE_GCM) { 1033afdbec36SLin Jinhan u32 aad_tmp_len = 0; 1034c3ce9937SLin Jinhan 1035c3ce9937SLin Jinhan aad_desc = align_malloc(sizeof(*aad_desc), LLI_ADDR_ALIGN_SIZE); 1036c3ce9937SLin Jinhan if (!aad_desc) 1037c3ce9937SLin Jinhan goto exit; 1038c3ce9937SLin Jinhan 1039c3ce9937SLin Jinhan memset(aad_desc, 0x00, sizeof(*aad_desc)); 1040c3ce9937SLin Jinhan aad_desc->next_addr = (u32)virt_to_phys(data_desc); 1041ce7f4cd6SLin Jinhan aad_desc->user_define = LLI_USER_CIPHER_START | 1042c3ce9937SLin Jinhan LLI_USER_STRING_START | 1043c3ce9937SLin Jinhan LLI_USER_STRING_LAST | 1044c3ce9937SLin Jinhan LLI_USER_STRING_AAD | 1045c3ce9937SLin Jinhan (key_chn << 4); 1046c3ce9937SLin Jinhan 1047c3ce9937SLin Jinhan if (rk_mode == RK_MODE_CCM) { 1048c3ce9937SLin Jinhan u8 padding[AES_BLOCK_SIZE]; 1049c3ce9937SLin Jinhan u32 padding_size = 0; 1050c3ce9937SLin Jinhan 1051c3ce9937SLin Jinhan memset(padding, 0x00, sizeof(padding)); 1052c3ce9937SLin Jinhan ccm_aad_padding(aad_len, padding, &padding_size); 1053c3ce9937SLin Jinhan 1054c3ce9937SLin Jinhan aad_tmp_len = aad_len + AES_BLOCK_SIZE + padding_size; 1055c3ce9937SLin Jinhan aad_tmp_len = ROUNDUP(aad_tmp_len, AES_BLOCK_SIZE); 1056c3ce9937SLin Jinhan aad_tmp = align_malloc(aad_tmp_len, 1057c3ce9937SLin Jinhan DATA_ADDR_ALIGN_SIZE); 1058c3ce9937SLin Jinhan if (!aad_tmp) 1059c3ce9937SLin Jinhan goto exit; 1060c3ce9937SLin Jinhan 10612db770efSLin Jinhan /* clear last block */ 1062c3ce9937SLin Jinhan memset(aad_tmp + aad_tmp_len - AES_BLOCK_SIZE, 1063c3ce9937SLin Jinhan 0x00, AES_BLOCK_SIZE); 10642db770efSLin Jinhan 10652db770efSLin Jinhan /* read iv data from reg */ 10662db770efSLin Jinhan get_iv_reg(key_chn, aad_tmp, AES_BLOCK_SIZE); 10672db770efSLin Jinhan ccm_compose_aad_iv(aad_tmp, tmp_len, aad_len, tag_len); 10682db770efSLin Jinhan memcpy(aad_tmp + AES_BLOCK_SIZE, padding, padding_size); 10692db770efSLin Jinhan 1070c3ce9937SLin Jinhan memcpy(aad_tmp + AES_BLOCK_SIZE + padding_size, 1071c3ce9937SLin Jinhan aad, aad_len); 1072c3ce9937SLin Jinhan } else { 1073c3ce9937SLin Jinhan aad_tmp_len = aad_len; 1074b83c40a4SLin Jinhan if (IS_ALIGNED((ulong)aad, DATA_ADDR_ALIGN_SIZE)) { 1075b83c40a4SLin Jinhan aad_tmp = (void *)aad; 1076b83c40a4SLin Jinhan } else { 1077c3ce9937SLin Jinhan aad_tmp = align_malloc(aad_tmp_len, 1078c3ce9937SLin Jinhan DATA_ADDR_ALIGN_SIZE); 1079c3ce9937SLin Jinhan if (!aad_tmp) 1080c3ce9937SLin Jinhan goto exit; 1081c3ce9937SLin Jinhan 1082c3ce9937SLin Jinhan memcpy(aad_tmp, aad, aad_tmp_len); 1083b83c40a4SLin Jinhan } 1084b83c40a4SLin Jinhan 1085c3ce9937SLin Jinhan set_aad_len_reg(key_chn, aad_tmp_len); 1086c3ce9937SLin Jinhan set_pc_len_reg(key_chn, tmp_len); 1087c3ce9937SLin Jinhan } 1088c3ce9937SLin Jinhan 1089c3ce9937SLin Jinhan aad_desc->src_addr = (u32)virt_to_phys(aad_tmp); 1090c3ce9937SLin Jinhan aad_desc->src_len = aad_tmp_len; 1091afdbec36SLin Jinhan 1092afdbec36SLin Jinhan if (aad_tmp_len) { 1093afdbec36SLin Jinhan data_desc->user_define = LLI_USER_STRING_START | 1094afdbec36SLin Jinhan LLI_USER_STRING_LAST | 1095afdbec36SLin Jinhan (key_chn << 4); 1096c3ce9937SLin Jinhan crypto_write((u32)virt_to_phys(aad_desc), CRYPTO_DMA_LLI_ADDR); 1097c3ce9937SLin Jinhan cache_op_inner(DCACHE_AREA_CLEAN, aad_tmp, aad_tmp_len); 1098c3ce9937SLin Jinhan cache_op_inner(DCACHE_AREA_CLEAN, aad_desc, sizeof(*aad_desc)); 1099afdbec36SLin Jinhan } 1100c3ce9937SLin Jinhan } 110149a2135eSLin Jinhan 110249a2135eSLin Jinhan cache_op_inner(DCACHE_AREA_CLEAN, data_desc, sizeof(*data_desc)); 110349a2135eSLin Jinhan cache_op_inner(DCACHE_AREA_CLEAN, dma_in, tmp_len); 110449a2135eSLin Jinhan cache_op_inner(DCACHE_AREA_INVALIDATE, dma_out, tmp_len); 110549a2135eSLin Jinhan 110649a2135eSLin Jinhan /* din_swap set 1, dout_swap set 1, default 1. */ 110749a2135eSLin Jinhan crypto_write(0x00030003, CRYPTO_FIFO_CTL); 1108fe0c4b19SLin Jinhan crypto_write(0, CRYPTO_DMA_INT_EN); 110949a2135eSLin Jinhan 111049a2135eSLin Jinhan reg_ctrl = crypto_read(CRYPTO_BC_CTL) | CRYPTO_BC_ENABLE; 111149a2135eSLin Jinhan crypto_write(reg_ctrl | CRYPTO_WRITE_MASK_ALL, CRYPTO_BC_CTL); 111249a2135eSLin Jinhan crypto_write(0x00010001, CRYPTO_DMA_CTL);//start 111349a2135eSLin Jinhan 111449a2135eSLin Jinhan mask = ~(mask | CRYPTO_SYNC_LOCKSTEP_INT_ST); 111549a2135eSLin Jinhan 111649a2135eSLin Jinhan /* wait calc ok */ 111749a2135eSLin Jinhan ret = RK_POLL_TIMEOUT(!(crypto_read(CRYPTO_DMA_INT_ST) & mask), 111849a2135eSLin Jinhan RK_CRYPTO_TIMEOUT); 111949a2135eSLin Jinhan tmp = crypto_read(CRYPTO_DMA_INT_ST); 112049a2135eSLin Jinhan crypto_write(tmp, CRYPTO_DMA_INT_ST); 112149a2135eSLin Jinhan 112249a2135eSLin Jinhan if ((tmp & mask) == expt_int) { 112349a2135eSLin Jinhan if (out && out != dma_out) 112449a2135eSLin Jinhan memcpy(out, dma_out, len); 1125d9332f1cSLin Jinhan 1126d9332f1cSLin Jinhan if (IS_NEED_TAG(rk_mode)) { 1127d9332f1cSLin Jinhan ret = WAIT_TAG_VALID(key_chn, RK_CRYPTO_TIMEOUT); 1128d9332f1cSLin Jinhan get_tag_from_reg(key_chn, tag, AES_BLOCK_SIZE); 1129d9332f1cSLin Jinhan } 113049a2135eSLin Jinhan } else { 11316b53126aSLin Jinhan dump_crypto_state(data_desc, tmp, expt_int, in, out, len, ret); 113249a2135eSLin Jinhan ret = -1; 113349a2135eSLin Jinhan } 113449a2135eSLin Jinhan 113549a2135eSLin Jinhan exit: 113649a2135eSLin Jinhan crypto_write(0xffff0000, CRYPTO_BC_CTL);//bc_ctl disable 113749a2135eSLin Jinhan align_free(data_desc); 1138c3ce9937SLin Jinhan align_free(aad_desc); 1139b83c40a4SLin Jinhan if (dma_in != in) 114049a2135eSLin Jinhan align_free(dma_in); 1141b83c40a4SLin Jinhan if (out && dma_out != out) 114249a2135eSLin Jinhan align_free(dma_out); 1143b83c40a4SLin Jinhan if (aad && aad != aad_tmp) 1144b83c40a4SLin Jinhan align_free(aad_tmp); 114549a2135eSLin Jinhan 114649a2135eSLin Jinhan return ret; 114749a2135eSLin Jinhan } 114849a2135eSLin Jinhan 114949a2135eSLin Jinhan static int hw_aes_init(u32 chn, const u8 *key, const u8 *twk_key, u32 key_len, 115049a2135eSLin Jinhan const u8 *iv, u32 iv_len, u32 mode, bool enc) 115149a2135eSLin Jinhan { 115249a2135eSLin Jinhan u32 rk_mode = RK_GET_RK_MODE(mode); 115349a2135eSLin Jinhan 1154d9332f1cSLin Jinhan if (rk_mode > RK_MODE_XTS) 1155d9332f1cSLin Jinhan return -EINVAL; 1156d9332f1cSLin Jinhan 115749a2135eSLin Jinhan if (iv_len > AES_BLOCK_SIZE) 115849a2135eSLin Jinhan return -EINVAL; 115949a2135eSLin Jinhan 1160d9332f1cSLin Jinhan if (IS_NEED_IV(rk_mode)) { 116149a2135eSLin Jinhan if (!iv || iv_len != AES_BLOCK_SIZE) 116249a2135eSLin Jinhan return -EINVAL; 116349a2135eSLin Jinhan } else { 116449a2135eSLin Jinhan iv_len = 0; 116549a2135eSLin Jinhan } 116649a2135eSLin Jinhan 116749a2135eSLin Jinhan if (rk_mode == RK_MODE_XTS) { 116849a2135eSLin Jinhan if (key_len != AES_KEYSIZE_128 && key_len != AES_KEYSIZE_256) 116949a2135eSLin Jinhan return -EINVAL; 117049a2135eSLin Jinhan 117149a2135eSLin Jinhan if (!key || !twk_key) 117249a2135eSLin Jinhan return -EINVAL; 117349a2135eSLin Jinhan } else { 117449a2135eSLin Jinhan if (key_len != AES_KEYSIZE_128 && 117549a2135eSLin Jinhan key_len != AES_KEYSIZE_192 && 117649a2135eSLin Jinhan key_len != AES_KEYSIZE_256) 117749a2135eSLin Jinhan return -EINVAL; 117849a2135eSLin Jinhan } 117949a2135eSLin Jinhan 118049a2135eSLin Jinhan return hw_cipher_init(chn, key, twk_key, key_len, iv, iv_len, 118149a2135eSLin Jinhan CRYPTO_AES, mode, enc); 118249a2135eSLin Jinhan } 118349a2135eSLin Jinhan 118449a2135eSLin Jinhan static int hw_sm4_init(u32 chn, const u8 *key, const u8 *twk_key, u32 key_len, 118549a2135eSLin Jinhan const u8 *iv, u32 iv_len, u32 mode, bool enc) 118649a2135eSLin Jinhan { 118749a2135eSLin Jinhan u32 rk_mode = RK_GET_RK_MODE(mode); 118849a2135eSLin Jinhan 1189d9332f1cSLin Jinhan if (rk_mode > RK_MODE_XTS) 1190d9332f1cSLin Jinhan return -EINVAL; 1191d9332f1cSLin Jinhan 119249a2135eSLin Jinhan if (iv_len > SM4_BLOCK_SIZE || key_len != SM4_KEYSIZE) 119349a2135eSLin Jinhan return -EINVAL; 119449a2135eSLin Jinhan 1195d9332f1cSLin Jinhan if (IS_NEED_IV(rk_mode)) { 119649a2135eSLin Jinhan if (!iv || iv_len != SM4_BLOCK_SIZE) 119749a2135eSLin Jinhan return -EINVAL; 119849a2135eSLin Jinhan } else { 119949a2135eSLin Jinhan iv_len = 0; 120049a2135eSLin Jinhan } 120149a2135eSLin Jinhan 120249a2135eSLin Jinhan if (rk_mode == RK_MODE_XTS) { 120349a2135eSLin Jinhan if (!key || !twk_key) 120449a2135eSLin Jinhan return -EINVAL; 120549a2135eSLin Jinhan } 120649a2135eSLin Jinhan 120749a2135eSLin Jinhan return hw_cipher_init(chn, key, twk_key, key_len, iv, iv_len, 120849a2135eSLin Jinhan CRYPTO_SM4, mode, enc); 120949a2135eSLin Jinhan } 121049a2135eSLin Jinhan 121149a2135eSLin Jinhan int rk_crypto_des(struct udevice *dev, u32 mode, const u8 *key, u32 key_len, 121249a2135eSLin Jinhan const u8 *iv, const u8 *in, u8 *out, u32 len, bool enc) 121349a2135eSLin Jinhan { 121449a2135eSLin Jinhan u32 rk_mode = RK_GET_RK_MODE(mode); 121549a2135eSLin Jinhan u8 tmp_key[24]; 121649a2135eSLin Jinhan int ret; 121749a2135eSLin Jinhan 121849a2135eSLin Jinhan if (!is_des_mode(rk_mode)) 121949a2135eSLin Jinhan return -EINVAL; 122049a2135eSLin Jinhan 122149a2135eSLin Jinhan if (key_len == DES_BLOCK_SIZE || key_len == 3 * DES_BLOCK_SIZE) { 122249a2135eSLin Jinhan memcpy(tmp_key, key, key_len); 122349a2135eSLin Jinhan } else if (key_len == 2 * DES_BLOCK_SIZE) { 122449a2135eSLin Jinhan memcpy(tmp_key, key, 16); 122549a2135eSLin Jinhan memcpy(tmp_key + 16, key, 8); 122649a2135eSLin Jinhan key_len = 3 * DES_BLOCK_SIZE; 122749a2135eSLin Jinhan } else { 122849a2135eSLin Jinhan return -EINVAL; 122949a2135eSLin Jinhan } 123049a2135eSLin Jinhan 123149a2135eSLin Jinhan ret = hw_cipher_init(0, tmp_key, NULL, key_len, iv, DES_BLOCK_SIZE, 123249a2135eSLin Jinhan CRYPTO_DES, mode, enc); 123349a2135eSLin Jinhan if (ret) 123449a2135eSLin Jinhan goto exit; 123549a2135eSLin Jinhan 123649a2135eSLin Jinhan ret = hw_cipher_crypt(in, out, len, NULL, 0, 123749a2135eSLin Jinhan NULL, 0, mode); 123849a2135eSLin Jinhan 123949a2135eSLin Jinhan exit: 124049a2135eSLin Jinhan return ret; 124149a2135eSLin Jinhan } 124249a2135eSLin Jinhan 124349a2135eSLin Jinhan int rk_crypto_aes(struct udevice *dev, u32 mode, 124449a2135eSLin Jinhan const u8 *key, const u8 *twk_key, u32 key_len, 124549a2135eSLin Jinhan const u8 *iv, u32 iv_len, 124649a2135eSLin Jinhan const u8 *in, u8 *out, u32 len, bool enc) 124749a2135eSLin Jinhan { 124849a2135eSLin Jinhan int ret; 124949a2135eSLin Jinhan 125049a2135eSLin Jinhan /* RV1126/RV1109 do not support aes-192 */ 125149a2135eSLin Jinhan #if defined(CONFIG_ROCKCHIP_RV1126) 125249a2135eSLin Jinhan if (key_len == AES_KEYSIZE_192) 125349a2135eSLin Jinhan return -EINVAL; 125449a2135eSLin Jinhan #endif 125549a2135eSLin Jinhan 125649a2135eSLin Jinhan ret = hw_aes_init(0, key, twk_key, key_len, iv, iv_len, mode, enc); 125749a2135eSLin Jinhan if (ret) 125849a2135eSLin Jinhan return ret; 125949a2135eSLin Jinhan 126049a2135eSLin Jinhan return hw_cipher_crypt(in, out, len, NULL, 0, 126149a2135eSLin Jinhan NULL, 0, mode); 126249a2135eSLin Jinhan } 126349a2135eSLin Jinhan 126449a2135eSLin Jinhan int rk_crypto_sm4(struct udevice *dev, u32 mode, 126549a2135eSLin Jinhan const u8 *key, const u8 *twk_key, u32 key_len, 126649a2135eSLin Jinhan const u8 *iv, u32 iv_len, 126749a2135eSLin Jinhan const u8 *in, u8 *out, u32 len, bool enc) 126849a2135eSLin Jinhan { 126949a2135eSLin Jinhan int ret; 127049a2135eSLin Jinhan 127149a2135eSLin Jinhan ret = hw_sm4_init(0, key, twk_key, key_len, iv, iv_len, mode, enc); 127249a2135eSLin Jinhan if (ret) 127349a2135eSLin Jinhan return ret; 127449a2135eSLin Jinhan 127549a2135eSLin Jinhan return hw_cipher_crypt(in, out, len, NULL, 0, NULL, 0, mode); 127649a2135eSLin Jinhan } 127749a2135eSLin Jinhan 127849a2135eSLin Jinhan int rockchip_crypto_cipher(struct udevice *dev, cipher_context *ctx, 127949a2135eSLin Jinhan const u8 *in, u8 *out, u32 len, bool enc) 128049a2135eSLin Jinhan { 1281dd7763a8SFinley Xiao int ret; 1282dd7763a8SFinley Xiao 1283dd7763a8SFinley Xiao rk_crypto_enable_clk(dev); 1284dd7763a8SFinley Xiao 128549a2135eSLin Jinhan switch (ctx->algo) { 128649a2135eSLin Jinhan case CRYPTO_DES: 1287dd7763a8SFinley Xiao ret = rk_crypto_des(dev, ctx->mode, ctx->key, ctx->key_len, 128849a2135eSLin Jinhan ctx->iv, in, out, len, enc); 12899b9c232aSLin Jinhan break; 129049a2135eSLin Jinhan case CRYPTO_AES: 1291dd7763a8SFinley Xiao ret = rk_crypto_aes(dev, ctx->mode, 129249a2135eSLin Jinhan ctx->key, ctx->twk_key, ctx->key_len, 129349a2135eSLin Jinhan ctx->iv, ctx->iv_len, in, out, len, enc); 12949b9c232aSLin Jinhan break; 129549a2135eSLin Jinhan case CRYPTO_SM4: 1296dd7763a8SFinley Xiao ret = rk_crypto_sm4(dev, ctx->mode, 129749a2135eSLin Jinhan ctx->key, ctx->twk_key, ctx->key_len, 129849a2135eSLin Jinhan ctx->iv, ctx->iv_len, in, out, len, enc); 12999b9c232aSLin Jinhan break; 130049a2135eSLin Jinhan default: 1301dd7763a8SFinley Xiao ret = -EINVAL; 13029b9c232aSLin Jinhan break; 130349a2135eSLin Jinhan } 1304dd7763a8SFinley Xiao 1305dd7763a8SFinley Xiao rk_crypto_disable_clk(dev); 1306dd7763a8SFinley Xiao 1307dd7763a8SFinley Xiao return ret; 130849a2135eSLin Jinhan } 1309d9332f1cSLin Jinhan 1310*eecb3765SLin Jinhan int rockchip_crypto_fw_cipher(struct udevice *dev, cipher_fw_context *ctx, 1311*eecb3765SLin Jinhan const u8 *in, u8 *out, u32 len, bool enc) 1312*eecb3765SLin Jinhan { 1313*eecb3765SLin Jinhan int ret; 1314*eecb3765SLin Jinhan 1315*eecb3765SLin Jinhan rk_crypto_enable_clk(dev); 1316*eecb3765SLin Jinhan 1317*eecb3765SLin Jinhan switch (ctx->algo) { 1318*eecb3765SLin Jinhan case CRYPTO_DES: 1319*eecb3765SLin Jinhan ret = rk_crypto_des(dev, ctx->mode, NULL, ctx->key_len, 1320*eecb3765SLin Jinhan ctx->iv, in, out, len, enc); 1321*eecb3765SLin Jinhan break; 1322*eecb3765SLin Jinhan case CRYPTO_AES: 1323*eecb3765SLin Jinhan ret = rk_crypto_aes(dev, ctx->mode, NULL, NULL, ctx->key_len, 1324*eecb3765SLin Jinhan ctx->iv, ctx->iv_len, in, out, len, enc); 1325*eecb3765SLin Jinhan break; 1326*eecb3765SLin Jinhan case CRYPTO_SM4: 1327*eecb3765SLin Jinhan ret = rk_crypto_sm4(dev, ctx->mode, NULL, NULL, ctx->key_len, 1328*eecb3765SLin Jinhan ctx->iv, ctx->iv_len, in, out, len, enc); 1329*eecb3765SLin Jinhan break; 1330*eecb3765SLin Jinhan default: 1331*eecb3765SLin Jinhan ret = -EINVAL; 1332*eecb3765SLin Jinhan break; 1333*eecb3765SLin Jinhan } 1334*eecb3765SLin Jinhan 1335*eecb3765SLin Jinhan rk_crypto_disable_clk(dev); 1336*eecb3765SLin Jinhan 1337*eecb3765SLin Jinhan return ret; 1338*eecb3765SLin Jinhan } 1339*eecb3765SLin Jinhan 1340d9332f1cSLin Jinhan int rk_crypto_mac(struct udevice *dev, u32 algo, u32 mode, 1341d9332f1cSLin Jinhan const u8 *key, u32 key_len, 1342d9332f1cSLin Jinhan const u8 *in, u32 len, u8 *tag) 1343d9332f1cSLin Jinhan { 1344d9332f1cSLin Jinhan u32 rk_mode = RK_GET_RK_MODE(mode); 1345d9332f1cSLin Jinhan int ret; 1346d9332f1cSLin Jinhan 1347d9332f1cSLin Jinhan if (!IS_MAC_MODE(rk_mode)) 1348d9332f1cSLin Jinhan return -EINVAL; 1349d9332f1cSLin Jinhan 1350d9332f1cSLin Jinhan if (algo != CRYPTO_AES && algo != CRYPTO_SM4) 1351d9332f1cSLin Jinhan return -EINVAL; 1352d9332f1cSLin Jinhan 1353d9332f1cSLin Jinhan /* RV1126/RV1109 do not support aes-192 */ 1354d9332f1cSLin Jinhan #if defined(CONFIG_ROCKCHIP_RV1126) 1355d9332f1cSLin Jinhan if (algo == CRYPTO_AES && key_len == AES_KEYSIZE_192) 1356d9332f1cSLin Jinhan return -EINVAL; 1357d9332f1cSLin Jinhan #endif 1358d9332f1cSLin Jinhan 1359d9332f1cSLin Jinhan ret = hw_cipher_init(g_key_chn, key, NULL, key_len, NULL, 0, 1360d9332f1cSLin Jinhan algo, mode, true); 1361d9332f1cSLin Jinhan if (ret) 1362d9332f1cSLin Jinhan return ret; 1363d9332f1cSLin Jinhan 1364d9332f1cSLin Jinhan return hw_cipher_crypt(in, NULL, len, NULL, 0, 1365d9332f1cSLin Jinhan tag, AES_BLOCK_SIZE, mode); 1366d9332f1cSLin Jinhan } 1367d9332f1cSLin Jinhan 1368d9332f1cSLin Jinhan int rockchip_crypto_mac(struct udevice *dev, cipher_context *ctx, 1369d9332f1cSLin Jinhan const u8 *in, u32 len, u8 *tag) 1370d9332f1cSLin Jinhan { 1371dd7763a8SFinley Xiao int ret = 0; 1372dd7763a8SFinley Xiao 1373dd7763a8SFinley Xiao rk_crypto_enable_clk(dev); 1374dd7763a8SFinley Xiao 1375dd7763a8SFinley Xiao ret = rk_crypto_mac(dev, ctx->algo, ctx->mode, 1376d9332f1cSLin Jinhan ctx->key, ctx->key_len, in, len, tag); 1377dd7763a8SFinley Xiao 1378dd7763a8SFinley Xiao rk_crypto_disable_clk(dev); 1379dd7763a8SFinley Xiao 1380dd7763a8SFinley Xiao return ret; 1381d9332f1cSLin Jinhan } 1382d9332f1cSLin Jinhan 1383c3ce9937SLin Jinhan int rk_crypto_ae(struct udevice *dev, u32 algo, u32 mode, 1384c3ce9937SLin Jinhan const u8 *key, u32 key_len, const u8 *nonce, u32 nonce_len, 1385c3ce9937SLin Jinhan const u8 *in, u32 len, const u8 *aad, u32 aad_len, 1386c3ce9937SLin Jinhan u8 *out, u8 *tag) 1387c3ce9937SLin Jinhan { 1388c3ce9937SLin Jinhan u32 rk_mode = RK_GET_RK_MODE(mode); 1389c3ce9937SLin Jinhan int ret; 1390c3ce9937SLin Jinhan 1391c3ce9937SLin Jinhan if (!IS_AE_MODE(rk_mode)) 1392c3ce9937SLin Jinhan return -EINVAL; 1393c3ce9937SLin Jinhan 1394afdbec36SLin Jinhan if (len == 0) 1395afdbec36SLin Jinhan return -EINVAL; 1396afdbec36SLin Jinhan 1397c3ce9937SLin Jinhan if (algo != CRYPTO_AES && algo != CRYPTO_SM4) 1398c3ce9937SLin Jinhan return -EINVAL; 1399c3ce9937SLin Jinhan 1400c3ce9937SLin Jinhan /* RV1126/RV1109 do not support aes-192 */ 1401c3ce9937SLin Jinhan #if defined(CONFIG_ROCKCHIP_RV1126) 1402c3ce9937SLin Jinhan if (algo == CRYPTO_AES && key_len == AES_KEYSIZE_192) 1403c3ce9937SLin Jinhan return -EINVAL; 1404c3ce9937SLin Jinhan #endif 1405c3ce9937SLin Jinhan 1406c3ce9937SLin Jinhan ret = hw_cipher_init(g_key_chn, key, NULL, key_len, nonce, nonce_len, 1407c3ce9937SLin Jinhan algo, mode, true); 1408c3ce9937SLin Jinhan if (ret) 1409c3ce9937SLin Jinhan return ret; 1410c3ce9937SLin Jinhan 1411c3ce9937SLin Jinhan return hw_cipher_crypt(in, out, len, aad, aad_len, 1412c3ce9937SLin Jinhan tag, AES_BLOCK_SIZE, mode); 1413c3ce9937SLin Jinhan } 1414c3ce9937SLin Jinhan 1415c3ce9937SLin Jinhan int rockchip_crypto_ae(struct udevice *dev, cipher_context *ctx, 1416c3ce9937SLin Jinhan const u8 *in, u32 len, const u8 *aad, u32 aad_len, 1417c3ce9937SLin Jinhan u8 *out, u8 *tag) 1418c3ce9937SLin Jinhan 1419c3ce9937SLin Jinhan { 1420dd7763a8SFinley Xiao int ret = 0; 1421dd7763a8SFinley Xiao 1422dd7763a8SFinley Xiao rk_crypto_enable_clk(dev); 1423dd7763a8SFinley Xiao 1424dd7763a8SFinley Xiao ret = rk_crypto_ae(dev, ctx->algo, ctx->mode, ctx->key, ctx->key_len, 1425c3ce9937SLin Jinhan ctx->iv, ctx->iv_len, in, len, 1426c3ce9937SLin Jinhan aad, aad_len, out, tag); 1427dd7763a8SFinley Xiao 1428dd7763a8SFinley Xiao rk_crypto_disable_clk(dev); 1429dd7763a8SFinley Xiao 1430dd7763a8SFinley Xiao return ret; 1431c3ce9937SLin Jinhan } 1432c3ce9937SLin Jinhan 1433*eecb3765SLin Jinhan static ulong rockchip_crypto_keytable_addr(struct udevice *dev) 1434*eecb3765SLin Jinhan { 1435*eecb3765SLin Jinhan return CRYPTO_S_BY_KEYLAD_BASE + CRYPTO_CH0_KEY_0; 1436*eecb3765SLin Jinhan } 1437*eecb3765SLin Jinhan 143849a2135eSLin Jinhan #endif 143949a2135eSLin Jinhan 1440864e581cSLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_RSA) 1441b353a43cSLin Jinhan static int rockchip_crypto_rsa_verify(struct udevice *dev, rsa_key *ctx, 1442b353a43cSLin Jinhan u8 *sign, u8 *output) 1443b353a43cSLin Jinhan { 1444b353a43cSLin Jinhan struct mpa_num *mpa_m = NULL, *mpa_e = NULL, *mpa_n = NULL; 1445b353a43cSLin Jinhan struct mpa_num *mpa_c = NULL, *mpa_result = NULL; 1446b353a43cSLin Jinhan u32 n_bits, n_words; 1447b353a43cSLin Jinhan int ret; 1448b353a43cSLin Jinhan 1449b353a43cSLin Jinhan if (!ctx) 1450b353a43cSLin Jinhan return -EINVAL; 1451b353a43cSLin Jinhan 1452b353a43cSLin Jinhan if (ctx->algo != CRYPTO_RSA512 && 1453b353a43cSLin Jinhan ctx->algo != CRYPTO_RSA1024 && 1454b353a43cSLin Jinhan ctx->algo != CRYPTO_RSA2048 && 1455b353a43cSLin Jinhan ctx->algo != CRYPTO_RSA3072 && 1456b353a43cSLin Jinhan ctx->algo != CRYPTO_RSA4096) 1457b353a43cSLin Jinhan return -EINVAL; 1458b353a43cSLin Jinhan 1459b353a43cSLin Jinhan n_bits = crypto_algo_nbits(ctx->algo); 1460b353a43cSLin Jinhan n_words = BITS2WORD(n_bits); 1461b353a43cSLin Jinhan 1462549a74f7SLin Jinhan ret = rk_mpa_alloc(&mpa_m, sign, n_words); 1463b353a43cSLin Jinhan if (ret) 1464b353a43cSLin Jinhan goto exit; 1465b353a43cSLin Jinhan 1466549a74f7SLin Jinhan ret = rk_mpa_alloc(&mpa_e, ctx->e, n_words); 1467549a74f7SLin Jinhan if (ret) 1468549a74f7SLin Jinhan goto exit; 1469b353a43cSLin Jinhan 1470549a74f7SLin Jinhan ret = rk_mpa_alloc(&mpa_n, ctx->n, n_words); 1471549a74f7SLin Jinhan if (ret) 1472549a74f7SLin Jinhan goto exit; 1473549a74f7SLin Jinhan 1474549a74f7SLin Jinhan if (ctx->c) { 1475549a74f7SLin Jinhan ret = rk_mpa_alloc(&mpa_c, ctx->c, n_words); 1476549a74f7SLin Jinhan if (ret) 1477549a74f7SLin Jinhan goto exit; 1478549a74f7SLin Jinhan } 1479549a74f7SLin Jinhan 1480549a74f7SLin Jinhan ret = rk_mpa_alloc(&mpa_result, NULL, n_words); 1481549a74f7SLin Jinhan if (ret) 1482549a74f7SLin Jinhan goto exit; 1483b353a43cSLin Jinhan 1484dd7763a8SFinley Xiao rk_crypto_enable_clk(dev); 1485b353a43cSLin Jinhan ret = rk_exptmod_np(mpa_m, mpa_e, mpa_n, mpa_c, mpa_result); 1486b353a43cSLin Jinhan if (!ret) 1487549a74f7SLin Jinhan memcpy(output, mpa_result->d, BITS2BYTE(n_bits)); 1488dd7763a8SFinley Xiao rk_crypto_disable_clk(dev); 1489b353a43cSLin Jinhan 1490b353a43cSLin Jinhan exit: 1491b353a43cSLin Jinhan rk_mpa_free(&mpa_m); 1492b353a43cSLin Jinhan rk_mpa_free(&mpa_e); 1493b353a43cSLin Jinhan rk_mpa_free(&mpa_n); 1494b353a43cSLin Jinhan rk_mpa_free(&mpa_c); 1495b353a43cSLin Jinhan rk_mpa_free(&mpa_result); 1496b353a43cSLin Jinhan 1497b353a43cSLin Jinhan return ret; 1498b353a43cSLin Jinhan } 1499864e581cSLin Jinhan #endif 1500b353a43cSLin Jinhan 150102b4cf42SLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_EC) 150202b4cf42SLin Jinhan static int rockchip_crypto_ec_verify(struct udevice *dev, ec_key *ctx, 150302b4cf42SLin Jinhan u8 *hash, u32 hash_len, u8 *sign) 150402b4cf42SLin Jinhan { 150502b4cf42SLin Jinhan struct mpa_num *bn_sign = NULL; 150602b4cf42SLin Jinhan struct rk_ecp_point point_P, point_sign; 150702b4cf42SLin Jinhan u32 n_bits, n_words; 150802b4cf42SLin Jinhan int ret; 150902b4cf42SLin Jinhan 151002b4cf42SLin Jinhan if (!ctx) 151102b4cf42SLin Jinhan return -EINVAL; 151202b4cf42SLin Jinhan 151302b4cf42SLin Jinhan if (ctx->algo != CRYPTO_SM2 && 151402b4cf42SLin Jinhan ctx->algo != CRYPTO_ECC_192R1 && 151502b4cf42SLin Jinhan ctx->algo != CRYPTO_ECC_224R1 && 151602b4cf42SLin Jinhan ctx->algo != CRYPTO_ECC_256R1) 151702b4cf42SLin Jinhan return -EINVAL; 151802b4cf42SLin Jinhan 151902b4cf42SLin Jinhan n_bits = crypto_algo_nbits(ctx->algo); 152002b4cf42SLin Jinhan n_words = BITS2WORD(n_bits); 152102b4cf42SLin Jinhan 152202b4cf42SLin Jinhan ret = rk_mpa_alloc(&bn_sign, sign, n_words); 152302b4cf42SLin Jinhan if (ret) 152402b4cf42SLin Jinhan goto exit; 152502b4cf42SLin Jinhan 152602b4cf42SLin Jinhan ret = rk_mpa_alloc(&point_P.x, ctx->x, n_words); 152702b4cf42SLin Jinhan ret |= rk_mpa_alloc(&point_P.y, ctx->y, n_words); 152802b4cf42SLin Jinhan if (ret) 152902b4cf42SLin Jinhan goto exit; 153002b4cf42SLin Jinhan 153102b4cf42SLin Jinhan ret = rk_mpa_alloc(&point_sign.x, sign, n_words); 153202b4cf42SLin Jinhan ret |= rk_mpa_alloc(&point_sign.y, sign + WORD2BYTE(n_words), n_words); 153302b4cf42SLin Jinhan if (ret) 153402b4cf42SLin Jinhan goto exit; 153502b4cf42SLin Jinhan 153602b4cf42SLin Jinhan rk_crypto_enable_clk(dev); 153702b4cf42SLin Jinhan ret = rockchip_ecc_verify(ctx->algo, hash, hash_len, &point_P, &point_sign); 153802b4cf42SLin Jinhan rk_crypto_disable_clk(dev); 153902b4cf42SLin Jinhan exit: 154002b4cf42SLin Jinhan rk_mpa_free(&bn_sign); 154102b4cf42SLin Jinhan rk_mpa_free(&point_P.x); 154202b4cf42SLin Jinhan rk_mpa_free(&point_P.y); 154302b4cf42SLin Jinhan rk_mpa_free(&point_sign.x); 154402b4cf42SLin Jinhan rk_mpa_free(&point_sign.y); 154502b4cf42SLin Jinhan 154602b4cf42SLin Jinhan return ret; 154702b4cf42SLin Jinhan } 154802b4cf42SLin Jinhan #endif 154902b4cf42SLin Jinhan 1550b353a43cSLin Jinhan static const struct dm_crypto_ops rockchip_crypto_ops = { 1551b353a43cSLin Jinhan .capability = rockchip_crypto_capability, 1552b353a43cSLin Jinhan .sha_init = rockchip_crypto_sha_init, 1553b353a43cSLin Jinhan .sha_update = rockchip_crypto_sha_update, 1554b353a43cSLin Jinhan .sha_final = rockchip_crypto_sha_final, 155549a2135eSLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_RSA) 1556b353a43cSLin Jinhan .rsa_verify = rockchip_crypto_rsa_verify, 155749a2135eSLin Jinhan #endif 155802b4cf42SLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_EC) 155902b4cf42SLin Jinhan .ec_verify = rockchip_crypto_ec_verify, 156002b4cf42SLin Jinhan #endif 156149a2135eSLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_HMAC) 156249a2135eSLin Jinhan .hmac_init = rockchip_crypto_hmac_init, 156349a2135eSLin Jinhan .hmac_update = rockchip_crypto_hmac_update, 156449a2135eSLin Jinhan .hmac_final = rockchip_crypto_hmac_final, 156549a2135eSLin Jinhan #endif 156649a2135eSLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_CIPHER) 156749a2135eSLin Jinhan .cipher_crypt = rockchip_crypto_cipher, 1568d9332f1cSLin Jinhan .cipher_mac = rockchip_crypto_mac, 1569c3ce9937SLin Jinhan .cipher_ae = rockchip_crypto_ae, 1570*eecb3765SLin Jinhan .cipher_fw_crypt = rockchip_crypto_fw_cipher, 1571*eecb3765SLin Jinhan .keytable_addr = rockchip_crypto_keytable_addr, 157249a2135eSLin Jinhan #endif 1573b353a43cSLin Jinhan }; 1574b353a43cSLin Jinhan 1575b353a43cSLin Jinhan /* 1576b353a43cSLin Jinhan * Only use "clocks" to parse crypto clock id and use rockchip_get_clk(). 1577b353a43cSLin Jinhan * Because we always add crypto node in U-Boot dts, when kernel dtb enabled : 1578b353a43cSLin Jinhan * 1579b353a43cSLin Jinhan * 1. There is cru phandle mismatch between U-Boot and kernel dtb; 1580b353a43cSLin Jinhan * 2. CONFIG_OF_SPL_REMOVE_PROPS removes clock property; 1581b353a43cSLin Jinhan */ 1582b353a43cSLin Jinhan static int rockchip_crypto_ofdata_to_platdata(struct udevice *dev) 1583b353a43cSLin Jinhan { 1584b353a43cSLin Jinhan struct rockchip_crypto_priv *priv = dev_get_priv(dev); 1585b353a43cSLin Jinhan int len, ret = -EINVAL; 1586b353a43cSLin Jinhan 1587a24b2aebSLin Jinhan memset(priv, 0x00, sizeof(*priv)); 1588a24b2aebSLin Jinhan 1589a24b2aebSLin Jinhan priv->reg = (fdt_addr_t)dev_read_addr_ptr(dev); 1590a24b2aebSLin Jinhan if (priv->reg == FDT_ADDR_T_NONE) 1591a24b2aebSLin Jinhan return -EINVAL; 1592a24b2aebSLin Jinhan 1593a24b2aebSLin Jinhan crypto_base = priv->reg; 1594a24b2aebSLin Jinhan 1595a24b2aebSLin Jinhan /* if there is no clocks in dts, just skip it */ 1596b353a43cSLin Jinhan if (!dev_read_prop(dev, "clocks", &len)) { 1597b353a43cSLin Jinhan printf("Can't find \"clocks\" property\n"); 1598a24b2aebSLin Jinhan return 0; 1599b353a43cSLin Jinhan } 1600b353a43cSLin Jinhan 1601b353a43cSLin Jinhan memset(priv, 0x00, sizeof(*priv)); 1602b353a43cSLin Jinhan priv->clocks = malloc(len); 1603b353a43cSLin Jinhan if (!priv->clocks) 1604b353a43cSLin Jinhan return -ENOMEM; 1605b353a43cSLin Jinhan 1606da703fb5SLin Jinhan priv->nclocks = len / (2 * sizeof(u32)); 1607b353a43cSLin Jinhan if (dev_read_u32_array(dev, "clocks", (u32 *)priv->clocks, 1608b353a43cSLin Jinhan priv->nclocks)) { 1609b353a43cSLin Jinhan printf("Can't read \"clocks\" property\n"); 1610b353a43cSLin Jinhan ret = -EINVAL; 1611b353a43cSLin Jinhan goto exit; 1612b353a43cSLin Jinhan } 1613b353a43cSLin Jinhan 1614da703fb5SLin Jinhan if (dev_read_prop(dev, "clock-frequency", &len)) { 1615b353a43cSLin Jinhan priv->frequencies = malloc(len); 1616b353a43cSLin Jinhan if (!priv->frequencies) { 1617b353a43cSLin Jinhan ret = -ENOMEM; 1618b353a43cSLin Jinhan goto exit; 1619b353a43cSLin Jinhan } 1620a8335d81SFinley Xiao priv->freq_nclocks = len / sizeof(u32); 1621b353a43cSLin Jinhan if (dev_read_u32_array(dev, "clock-frequency", priv->frequencies, 1622da703fb5SLin Jinhan priv->freq_nclocks)) { 1623b353a43cSLin Jinhan printf("Can't read \"clock-frequency\" property\n"); 1624b353a43cSLin Jinhan ret = -EINVAL; 1625b353a43cSLin Jinhan goto exit; 1626b353a43cSLin Jinhan } 1627da703fb5SLin Jinhan } 1628b353a43cSLin Jinhan 1629b353a43cSLin Jinhan return 0; 1630b353a43cSLin Jinhan exit: 1631b353a43cSLin Jinhan if (priv->clocks) 1632b353a43cSLin Jinhan free(priv->clocks); 1633b353a43cSLin Jinhan 1634b353a43cSLin Jinhan if (priv->frequencies) 1635b353a43cSLin Jinhan free(priv->frequencies); 1636b353a43cSLin Jinhan 1637b353a43cSLin Jinhan return ret; 1638b353a43cSLin Jinhan } 1639b353a43cSLin Jinhan 16406cebff12SJoseph Chen static int rk_crypto_set_clk(struct udevice *dev) 1641b353a43cSLin Jinhan { 16426cebff12SJoseph Chen struct rockchip_crypto_priv *priv = dev_get_priv(dev); 16436cebff12SJoseph Chen struct clk clk; 1644a24b2aebSLin Jinhan int i, ret; 1645b353a43cSLin Jinhan 1646a8335d81SFinley Xiao /* use standard "assigned-clock-rates" props */ 1647a8335d81SFinley Xiao if (dev_read_size(dev, "assigned-clock-rates") > 0) 1648a8335d81SFinley Xiao return clk_set_defaults(dev); 1649da703fb5SLin Jinhan 1650a8335d81SFinley Xiao /* use "clock-frequency" props */ 1651da703fb5SLin Jinhan if (priv->freq_nclocks == 0) 1652a24b2aebSLin Jinhan return 0; 165349a2135eSLin Jinhan 1654da703fb5SLin Jinhan for (i = 0; i < priv->freq_nclocks; i++) { 16556cebff12SJoseph Chen ret = clk_get_by_index(dev, i, &clk); 16566cebff12SJoseph Chen if (ret < 0) { 16576cebff12SJoseph Chen printf("Failed to get clk index %d, ret=%d\n", i, ret); 1658b353a43cSLin Jinhan return ret; 1659b353a43cSLin Jinhan } 16606cebff12SJoseph Chen ret = clk_set_rate(&clk, priv->frequencies[i]); 1661b353a43cSLin Jinhan if (ret < 0) { 1662b353a43cSLin Jinhan printf("%s: Failed to set clk(%ld): ret=%d\n", 16636cebff12SJoseph Chen __func__, clk.id, ret); 1664b353a43cSLin Jinhan return ret; 1665b353a43cSLin Jinhan } 1666b353a43cSLin Jinhan } 1667b353a43cSLin Jinhan 1668a24b2aebSLin Jinhan return 0; 1669a24b2aebSLin Jinhan } 1670a24b2aebSLin Jinhan 1671a24b2aebSLin Jinhan static int rockchip_crypto_probe(struct udevice *dev) 1672a24b2aebSLin Jinhan { 1673a24b2aebSLin Jinhan struct rockchip_crypto_priv *priv = dev_get_priv(dev); 1674a24b2aebSLin Jinhan struct rk_crypto_soc_data *sdata; 1675a24b2aebSLin Jinhan int ret = 0; 1676a24b2aebSLin Jinhan 1677a24b2aebSLin Jinhan sdata = (struct rk_crypto_soc_data *)dev_get_driver_data(dev); 167858432b6fSLin Jinhan 167958432b6fSLin Jinhan if (sdata->dynamic_cap) 168058432b6fSLin Jinhan sdata->capability = sdata->dynamic_cap(); 168158432b6fSLin Jinhan 1682a24b2aebSLin Jinhan priv->soc_data = sdata; 1683a24b2aebSLin Jinhan 1684a24b2aebSLin Jinhan priv->hw_ctx = memalign(LLI_ADDR_ALIGN_SIZE, 1685a24b2aebSLin Jinhan sizeof(struct rk_hash_ctx)); 1686a24b2aebSLin Jinhan if (!priv->hw_ctx) 1687a24b2aebSLin Jinhan return -ENOMEM; 1688a24b2aebSLin Jinhan 16896cebff12SJoseph Chen ret = rk_crypto_set_clk(dev); 1690a24b2aebSLin Jinhan if (ret) 1691a24b2aebSLin Jinhan return ret; 1692a24b2aebSLin Jinhan 1693f2c2c30cSLin Jinhan rk_crypto_enable_clk(dev); 1694f2c2c30cSLin Jinhan 1695b353a43cSLin Jinhan hw_crypto_reset(); 1696b353a43cSLin Jinhan 1697f2c2c30cSLin Jinhan rk_crypto_disable_clk(dev); 1698f2c2c30cSLin Jinhan 1699b353a43cSLin Jinhan return 0; 1700b353a43cSLin Jinhan } 1701b353a43cSLin Jinhan 170249a2135eSLin Jinhan static const struct rk_crypto_soc_data soc_data_base = { 170349a2135eSLin Jinhan .capability = CRYPTO_MD5 | 170449a2135eSLin Jinhan CRYPTO_SHA1 | 170549a2135eSLin Jinhan CRYPTO_SHA256 | 170649a2135eSLin Jinhan CRYPTO_SHA512 | 170749a2135eSLin Jinhan CRYPTO_HMAC_MD5 | 170849a2135eSLin Jinhan CRYPTO_HMAC_SHA1 | 170949a2135eSLin Jinhan CRYPTO_HMAC_SHA256 | 171049a2135eSLin Jinhan CRYPTO_HMAC_SHA512 | 171149a2135eSLin Jinhan CRYPTO_RSA512 | 171249a2135eSLin Jinhan CRYPTO_RSA1024 | 171349a2135eSLin Jinhan CRYPTO_RSA2048 | 171449a2135eSLin Jinhan CRYPTO_RSA3072 | 171549a2135eSLin Jinhan CRYPTO_RSA4096 | 171649a2135eSLin Jinhan CRYPTO_DES | 171749a2135eSLin Jinhan CRYPTO_AES, 171849a2135eSLin Jinhan }; 171949a2135eSLin Jinhan 172049a2135eSLin Jinhan static const struct rk_crypto_soc_data soc_data_base_sm = { 172149a2135eSLin Jinhan .capability = CRYPTO_MD5 | 172249a2135eSLin Jinhan CRYPTO_SHA1 | 172349a2135eSLin Jinhan CRYPTO_SHA256 | 172449a2135eSLin Jinhan CRYPTO_SHA512 | 172549a2135eSLin Jinhan CRYPTO_SM3 | 172649a2135eSLin Jinhan CRYPTO_HMAC_MD5 | 172749a2135eSLin Jinhan CRYPTO_HMAC_SHA1 | 172849a2135eSLin Jinhan CRYPTO_HMAC_SHA256 | 172949a2135eSLin Jinhan CRYPTO_HMAC_SHA512 | 173049a2135eSLin Jinhan CRYPTO_HMAC_SM3 | 173149a2135eSLin Jinhan CRYPTO_RSA512 | 173249a2135eSLin Jinhan CRYPTO_RSA1024 | 173349a2135eSLin Jinhan CRYPTO_RSA2048 | 173449a2135eSLin Jinhan CRYPTO_RSA3072 | 173549a2135eSLin Jinhan CRYPTO_RSA4096 | 173649a2135eSLin Jinhan CRYPTO_DES | 173749a2135eSLin Jinhan CRYPTO_AES | 173849a2135eSLin Jinhan CRYPTO_SM4, 173949a2135eSLin Jinhan }; 174049a2135eSLin Jinhan 174149a2135eSLin Jinhan static const struct rk_crypto_soc_data soc_data_rk1808 = { 174249a2135eSLin Jinhan .capability = CRYPTO_MD5 | 174349a2135eSLin Jinhan CRYPTO_SHA1 | 174449a2135eSLin Jinhan CRYPTO_SHA256 | 174549a2135eSLin Jinhan CRYPTO_HMAC_MD5 | 174649a2135eSLin Jinhan CRYPTO_HMAC_SHA1 | 174749a2135eSLin Jinhan CRYPTO_HMAC_SHA256 | 174849a2135eSLin Jinhan CRYPTO_RSA512 | 174949a2135eSLin Jinhan CRYPTO_RSA1024 | 175049a2135eSLin Jinhan CRYPTO_RSA2048 | 175149a2135eSLin Jinhan CRYPTO_RSA3072 | 175249a2135eSLin Jinhan CRYPTO_RSA4096, 175349a2135eSLin Jinhan }; 175449a2135eSLin Jinhan 175558432b6fSLin Jinhan static const struct rk_crypto_soc_data soc_data_cryptov3 = { 175658432b6fSLin Jinhan .capability = 0, 175758432b6fSLin Jinhan .dynamic_cap = crypto_v3_dynamic_cap, 175858432b6fSLin Jinhan }; 175958432b6fSLin Jinhan 1760b353a43cSLin Jinhan static const struct udevice_id rockchip_crypto_ids[] = { 176149a2135eSLin Jinhan { 176249a2135eSLin Jinhan .compatible = "rockchip,px30-crypto", 176349a2135eSLin Jinhan .data = (ulong)&soc_data_base 176449a2135eSLin Jinhan }, 176549a2135eSLin Jinhan { 176649a2135eSLin Jinhan .compatible = "rockchip,rk1808-crypto", 176749a2135eSLin Jinhan .data = (ulong)&soc_data_rk1808 176849a2135eSLin Jinhan }, 176949a2135eSLin Jinhan { 177049a2135eSLin Jinhan .compatible = "rockchip,rk3308-crypto", 177149a2135eSLin Jinhan .data = (ulong)&soc_data_base 177249a2135eSLin Jinhan }, 177349a2135eSLin Jinhan { 177449a2135eSLin Jinhan .compatible = "rockchip,rv1126-crypto", 177549a2135eSLin Jinhan .data = (ulong)&soc_data_base_sm 177649a2135eSLin Jinhan }, 177749a2135eSLin Jinhan { 177849a2135eSLin Jinhan .compatible = "rockchip,rk3568-crypto", 177949a2135eSLin Jinhan .data = (ulong)&soc_data_base_sm 178049a2135eSLin Jinhan }, 17815b3e3895SLin Jinhan { 17825b3e3895SLin Jinhan .compatible = "rockchip,rk3588-crypto", 17835b3e3895SLin Jinhan .data = (ulong)&soc_data_base_sm 17845b3e3895SLin Jinhan }, 178558432b6fSLin Jinhan { 1786f93f9077SLin Jinhan .compatible = "rockchip,crypto-v3", 178758432b6fSLin Jinhan .data = (ulong)&soc_data_cryptov3 178858432b6fSLin Jinhan }, 17892bcebb1aSLin Jinhan { 17902bcebb1aSLin Jinhan .compatible = "rockchip,crypto-v4", 17912bcebb1aSLin Jinhan .data = (ulong)&soc_data_cryptov3 /* reuse crypto v3 config */ 17922bcebb1aSLin Jinhan }, 1793b353a43cSLin Jinhan { } 1794b353a43cSLin Jinhan }; 1795b353a43cSLin Jinhan 1796b353a43cSLin Jinhan U_BOOT_DRIVER(rockchip_crypto_v2) = { 1797b353a43cSLin Jinhan .name = "rockchip_crypto_v2", 1798b353a43cSLin Jinhan .id = UCLASS_CRYPTO, 1799b353a43cSLin Jinhan .of_match = rockchip_crypto_ids, 1800b353a43cSLin Jinhan .ops = &rockchip_crypto_ops, 1801b353a43cSLin Jinhan .probe = rockchip_crypto_probe, 1802b353a43cSLin Jinhan .ofdata_to_platdata = rockchip_crypto_ofdata_to_platdata, 1803b353a43cSLin Jinhan .priv_auto_alloc_size = sizeof(struct rockchip_crypto_priv), 1804b353a43cSLin Jinhan }; 1805