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> 11b353a43cSLin Jinhan #include <asm/arch/hardware.h> 12b353a43cSLin Jinhan #include <asm/arch/clock.h> 13c48f1acfSLin Jinhan #include <rockchip/crypto_hash_cache.h> 14b353a43cSLin Jinhan #include <rockchip/crypto_v2.h> 15b353a43cSLin Jinhan #include <rockchip/crypto_v2_pka.h> 16b353a43cSLin Jinhan 17c48f1acfSLin Jinhan #define RK_HASH_CTX_MAGIC 0x1A1A1A1A 18c48f1acfSLin Jinhan 1949a2135eSLin Jinhan #ifdef DEBUG 2049a2135eSLin Jinhan #define IMSG(format, ...) printf("[%s, %05d]-trace: " format "\n", \ 2149a2135eSLin Jinhan __func__, __LINE__, ##__VA_ARGS__) 2249a2135eSLin Jinhan #else 2349a2135eSLin Jinhan #define IMSG(format, ...) 2449a2135eSLin Jinhan #endif 25c48f1acfSLin Jinhan 26c48f1acfSLin Jinhan struct crypto_lli_desc { 27c48f1acfSLin Jinhan u32 src_addr; 28c48f1acfSLin Jinhan u32 src_len; 29c48f1acfSLin Jinhan u32 dst_addr; 30c48f1acfSLin Jinhan u32 dst_len; 31c48f1acfSLin Jinhan u32 user_define; 32c48f1acfSLin Jinhan u32 reserve; 33c48f1acfSLin Jinhan u32 dma_ctrl; 34c48f1acfSLin Jinhan u32 next_addr; 35c48f1acfSLin Jinhan }; 36c48f1acfSLin Jinhan 37c48f1acfSLin Jinhan struct rk_hash_ctx { 38c48f1acfSLin Jinhan struct crypto_lli_desc data_lli; /* lli desc */ 39c48f1acfSLin Jinhan struct crypto_hash_cache *hash_cache; 40c48f1acfSLin Jinhan u32 magic; /* to check ctx */ 41c48f1acfSLin Jinhan u32 algo; /* hash algo */ 42c48f1acfSLin Jinhan u8 digest_size; /* hash out length */ 43c48f1acfSLin Jinhan u8 reserved[3]; 44c48f1acfSLin Jinhan }; 45c48f1acfSLin Jinhan 4649a2135eSLin Jinhan struct rk_crypto_soc_data { 4749a2135eSLin Jinhan u32 capability; 4849a2135eSLin Jinhan }; 4949a2135eSLin Jinhan 50b353a43cSLin Jinhan struct rockchip_crypto_priv { 51b353a43cSLin Jinhan fdt_addr_t reg; 52b353a43cSLin Jinhan struct clk clk; 53b353a43cSLin Jinhan u32 frequency; 54b353a43cSLin Jinhan char *clocks; 55b353a43cSLin Jinhan u32 *frequencies; 56b353a43cSLin Jinhan u32 nclocks; 57b353a43cSLin Jinhan u32 length; 581606a214SLin Jinhan struct rk_hash_ctx *hw_ctx; 5949a2135eSLin Jinhan struct rk_crypto_soc_data *soc_data; 60b353a43cSLin Jinhan }; 61b353a43cSLin Jinhan 6249a2135eSLin Jinhan #define LLI_ADDR_ALIGN_SIZE 8 6349a2135eSLin Jinhan #define DATA_ADDR_ALIGN_SIZE 8 6449a2135eSLin Jinhan #define DATA_LEN_ALIGN_SIZE 64 651606a214SLin Jinhan 66086e8fa8SLin Jinhan /* crypto timeout 500ms, must support more than 32M data per times*/ 67086e8fa8SLin Jinhan #define HASH_UPDATE_LIMIT (32 * 1024 * 1024) 6849a2135eSLin Jinhan #define RK_CRYPTO_TIMEOUT 500000 69b353a43cSLin Jinhan 7049a2135eSLin Jinhan #define RK_POLL_TIMEOUT(condition, timeout) \ 7149a2135eSLin Jinhan ({ \ 7249a2135eSLin Jinhan int time_out = timeout; \ 73b353a43cSLin Jinhan while (condition) { \ 7449a2135eSLin Jinhan if (--time_out <= 0) { \ 751606a214SLin Jinhan debug("[%s] %d: time out!\n", __func__,\ 76b353a43cSLin Jinhan __LINE__); \ 77b353a43cSLin Jinhan break; \ 78b353a43cSLin Jinhan } \ 79b353a43cSLin Jinhan udelay(1); \ 80b353a43cSLin Jinhan } \ 8149a2135eSLin Jinhan (time_out <= 0) ? -ETIMEDOUT : 0; \ 8249a2135eSLin Jinhan }) 83b353a43cSLin Jinhan 84d9332f1cSLin Jinhan #define WAIT_TAG_VALID(channel, timeout) ({ \ 85d9332f1cSLin Jinhan u32 tag_mask = CRYPTO_CH0_TAG_VALID << (channel);\ 86d9332f1cSLin Jinhan int ret;\ 87d9332f1cSLin Jinhan ret = RK_POLL_TIMEOUT(!(crypto_read(CRYPTO_TAG_VALID) & tag_mask),\ 88d9332f1cSLin Jinhan timeout);\ 89d9332f1cSLin Jinhan crypto_write(crypto_read(CRYPTO_TAG_VALID) & tag_mask, CRYPTO_TAG_VALID);\ 90d9332f1cSLin Jinhan ret;\ 91d9332f1cSLin Jinhan }) 92d9332f1cSLin Jinhan 93b353a43cSLin Jinhan #define virt_to_phys(addr) (((unsigned long)addr) & 0xffffffff) 94b353a43cSLin Jinhan #define phys_to_virt(addr, area) ((unsigned long)addr) 95b353a43cSLin Jinhan 9649a2135eSLin Jinhan #define align_malloc(bytes, alignment) memalign(alignment, bytes) 9749a2135eSLin Jinhan #define align_free(addr) free(addr) 9849a2135eSLin Jinhan 9949a2135eSLin Jinhan #define ROUNDUP(size, alignment) round_up(size, alignment) 10049a2135eSLin Jinhan #define cache_op_inner(type, addr, size) \ 10149a2135eSLin Jinhan crypto_flush_cacheline((ulong)addr, size) 10249a2135eSLin Jinhan 103d9332f1cSLin Jinhan #define IS_NEED_IV(rk_mode) ((rk_mode) != RK_MODE_ECB && \ 104d9332f1cSLin Jinhan (rk_mode) != RK_MODE_CMAC && \ 105d9332f1cSLin Jinhan (rk_mode) != RK_MODE_CBC_MAC) 106d9332f1cSLin Jinhan 107d9332f1cSLin Jinhan #define IS_NEED_TAG(rk_mode) ((rk_mode) == RK_MODE_CMAC || \ 108c3ce9937SLin Jinhan (rk_mode) == RK_MODE_CBC_MAC || \ 109c3ce9937SLin Jinhan (rk_mode) == RK_MODE_CCM || \ 110c3ce9937SLin Jinhan (rk_mode) == RK_MODE_GCM) 111d9332f1cSLin Jinhan 112d9332f1cSLin Jinhan #define IS_MAC_MODE(rk_mode) ((rk_mode) == RK_MODE_CMAC || \ 113d9332f1cSLin Jinhan (rk_mode) == RK_MODE_CBC_MAC) 114d9332f1cSLin Jinhan 115c3ce9937SLin Jinhan #define IS_AE_MODE(rk_mode) ((rk_mode) == RK_MODE_CCM || \ 116c3ce9937SLin Jinhan (rk_mode) == RK_MODE_GCM) 117c3ce9937SLin Jinhan 118b353a43cSLin Jinhan fdt_addr_t crypto_base; 119b353a43cSLin Jinhan 12049a2135eSLin Jinhan static inline void word2byte_be(u32 word, u8 *ch) 121b353a43cSLin Jinhan { 122b353a43cSLin Jinhan ch[0] = (word >> 24) & 0xff; 123b353a43cSLin Jinhan ch[1] = (word >> 16) & 0xff; 124b353a43cSLin Jinhan ch[2] = (word >> 8) & 0xff; 125b353a43cSLin Jinhan ch[3] = (word >> 0) & 0xff; 126b353a43cSLin Jinhan } 127b353a43cSLin Jinhan 12849a2135eSLin Jinhan static inline u32 byte2word_be(const u8 *ch) 12949a2135eSLin Jinhan { 13049a2135eSLin Jinhan return (*ch << 24) + (*(ch + 1) << 16) + (*(ch + 2) << 8) + *(ch + 3); 13149a2135eSLin Jinhan } 13249a2135eSLin Jinhan 13349a2135eSLin Jinhan static inline void clear_regs(u32 base, u32 words) 134b353a43cSLin Jinhan { 135b353a43cSLin Jinhan int i; 136b353a43cSLin Jinhan 137b353a43cSLin Jinhan /*clear out register*/ 13849a2135eSLin Jinhan for (i = 0; i < words; i++) 13949a2135eSLin Jinhan crypto_write(0, base + 4 * i); 14049a2135eSLin Jinhan } 14149a2135eSLin Jinhan 14249a2135eSLin Jinhan static inline void clear_hash_out_reg(void) 14349a2135eSLin Jinhan { 14449a2135eSLin Jinhan clear_regs(CRYPTO_HASH_DOUT_0, 16); 14549a2135eSLin Jinhan } 14649a2135eSLin Jinhan 14749a2135eSLin Jinhan static inline void clear_key_regs(void) 14849a2135eSLin Jinhan { 14949a2135eSLin Jinhan clear_regs(CRYPTO_CH0_KEY_0, CRYPTO_KEY_CHANNEL_NUM * 4); 15049a2135eSLin Jinhan } 15149a2135eSLin Jinhan 152c3ce9937SLin Jinhan static inline void read_regs(u32 base, u8 *data, u32 data_len) 153c3ce9937SLin Jinhan { 154c3ce9937SLin Jinhan u8 tmp_buf[4]; 155c3ce9937SLin Jinhan u32 i; 156c3ce9937SLin Jinhan 157c3ce9937SLin Jinhan for (i = 0; i < data_len / 4; i++) 158c3ce9937SLin Jinhan word2byte_be(crypto_read(base + i * 4), 159c3ce9937SLin Jinhan data + i * 4); 160c3ce9937SLin Jinhan 161c3ce9937SLin Jinhan if (data_len % 4) { 162c3ce9937SLin Jinhan word2byte_be(crypto_read(base + i * 4), tmp_buf); 163c3ce9937SLin Jinhan memcpy(data + i * 4, tmp_buf, data_len % 4); 164c3ce9937SLin Jinhan } 165c3ce9937SLin Jinhan } 166c3ce9937SLin Jinhan 16749a2135eSLin Jinhan static inline void write_regs(u32 base, const u8 *data, u32 data_len) 16849a2135eSLin Jinhan { 16949a2135eSLin Jinhan u8 tmp_buf[4]; 17049a2135eSLin Jinhan u32 i; 17149a2135eSLin Jinhan 17249a2135eSLin Jinhan for (i = 0; i < data_len / 4; i++, base += 4) 17349a2135eSLin Jinhan crypto_write(byte2word_be(data + i * 4), base); 17449a2135eSLin Jinhan 17549a2135eSLin Jinhan if (data_len % 4) { 17649a2135eSLin Jinhan memset(tmp_buf, 0x00, sizeof(tmp_buf)); 17749a2135eSLin Jinhan memcpy((u8 *)tmp_buf, data + i * 4, data_len % 4); 17849a2135eSLin Jinhan crypto_write(byte2word_be(tmp_buf), base); 17949a2135eSLin Jinhan } 18049a2135eSLin Jinhan } 18149a2135eSLin Jinhan 18249a2135eSLin Jinhan static inline void write_key_reg(u32 chn, const u8 *key, u32 key_len) 18349a2135eSLin Jinhan { 18449a2135eSLin Jinhan write_regs(CRYPTO_CH0_KEY_0 + chn * 0x10, key, key_len); 18549a2135eSLin Jinhan } 18649a2135eSLin Jinhan 18749a2135eSLin Jinhan static inline void set_iv_reg(u32 chn, const u8 *iv, u32 iv_len) 18849a2135eSLin Jinhan { 18949a2135eSLin Jinhan u32 base_iv; 19049a2135eSLin Jinhan 19149a2135eSLin Jinhan base_iv = CRYPTO_CH0_IV_0 + chn * 0x10; 19249a2135eSLin Jinhan 19349a2135eSLin Jinhan /* clear iv */ 19449a2135eSLin Jinhan clear_regs(base_iv, 4); 19549a2135eSLin Jinhan 19649a2135eSLin Jinhan if (!iv || iv_len == 0) 19749a2135eSLin Jinhan return; 19849a2135eSLin Jinhan 19949a2135eSLin Jinhan write_regs(base_iv, iv, iv_len); 20049a2135eSLin Jinhan 20149a2135eSLin Jinhan crypto_write(iv_len, CRYPTO_CH0_IV_LEN_0 + 4 * chn); 202b353a43cSLin Jinhan } 203b353a43cSLin Jinhan 204c3ce9937SLin Jinhan static inline void get_iv_reg(u32 chn, u8 *iv, u32 iv_len) 205c3ce9937SLin Jinhan { 206c3ce9937SLin Jinhan u32 base_iv; 207c3ce9937SLin Jinhan 208c3ce9937SLin Jinhan base_iv = CRYPTO_CH0_IV_0 + chn * 0x10; 209c3ce9937SLin Jinhan 210c3ce9937SLin Jinhan read_regs(base_iv, iv, iv_len); 211c3ce9937SLin Jinhan } 212c3ce9937SLin Jinhan 213d9332f1cSLin Jinhan static inline void get_tag_from_reg(u32 chn, u8 *tag, u32 tag_len) 214d9332f1cSLin Jinhan { 215d9332f1cSLin Jinhan u32 i; 216d9332f1cSLin Jinhan u32 chn_base = CRYPTO_CH0_TAG_0 + 0x10 * chn; 217d9332f1cSLin Jinhan 218d9332f1cSLin Jinhan for (i = 0; i < tag_len / 4; i++, chn_base += 4) 219d9332f1cSLin Jinhan word2byte_be(crypto_read(chn_base), tag + 4 * i); 220d9332f1cSLin Jinhan } 221d9332f1cSLin Jinhan 222b353a43cSLin Jinhan static int hw_crypto_reset(void) 223b353a43cSLin Jinhan { 22449a2135eSLin Jinhan u32 val = 0, mask = 0; 225b353a43cSLin Jinhan int ret; 226b353a43cSLin Jinhan 22749a2135eSLin Jinhan val = CRYPTO_SW_PKA_RESET | CRYPTO_SW_CC_RESET; 22849a2135eSLin Jinhan mask = val << CRYPTO_WRITE_MASK_SHIFT; 229b353a43cSLin Jinhan 230b353a43cSLin Jinhan /* reset pka and crypto modules*/ 23149a2135eSLin Jinhan crypto_write(val | mask, CRYPTO_RST_CTL); 232b353a43cSLin Jinhan 233b353a43cSLin Jinhan /* wait reset compelete */ 23449a2135eSLin Jinhan ret = RK_POLL_TIMEOUT(crypto_read(CRYPTO_RST_CTL), RK_CRYPTO_TIMEOUT); 23549a2135eSLin Jinhan 236b353a43cSLin Jinhan return ret; 237b353a43cSLin Jinhan } 238b353a43cSLin Jinhan 239b353a43cSLin Jinhan static void hw_hash_clean_ctx(struct rk_hash_ctx *ctx) 240b353a43cSLin Jinhan { 241b353a43cSLin Jinhan /* clear hash status */ 242b353a43cSLin Jinhan crypto_write(CRYPTO_WRITE_MASK_ALL | 0, CRYPTO_HASH_CTL); 243b353a43cSLin Jinhan 2441606a214SLin Jinhan assert(ctx); 2451606a214SLin Jinhan assert(ctx->magic == RK_HASH_CTX_MAGIC); 2461606a214SLin Jinhan 247c48f1acfSLin Jinhan crypto_hash_cache_free(ctx->hash_cache); 2481606a214SLin Jinhan 2491606a214SLin Jinhan memset(ctx, 0x00, sizeof(*ctx)); 250b353a43cSLin Jinhan } 251b353a43cSLin Jinhan 252c48f1acfSLin Jinhan static int rk_hash_init(void *hw_ctx, u32 algo) 253b353a43cSLin Jinhan { 254b353a43cSLin Jinhan struct rk_hash_ctx *tmp_ctx = (struct rk_hash_ctx *)hw_ctx; 255b353a43cSLin Jinhan u32 reg_ctrl = 0; 256b353a43cSLin Jinhan int ret; 257b353a43cSLin Jinhan 258b353a43cSLin Jinhan if (!tmp_ctx) 259b353a43cSLin Jinhan return -EINVAL; 260b353a43cSLin Jinhan 2611606a214SLin Jinhan reg_ctrl = CRYPTO_SW_CC_RESET; 2621606a214SLin Jinhan crypto_write(reg_ctrl | (reg_ctrl << CRYPTO_WRITE_MASK_SHIFT), 2631606a214SLin Jinhan CRYPTO_RST_CTL); 2641606a214SLin Jinhan 2651606a214SLin Jinhan /* wait reset compelete */ 26649a2135eSLin Jinhan ret = RK_POLL_TIMEOUT(crypto_read(CRYPTO_RST_CTL), 26749a2135eSLin Jinhan RK_CRYPTO_TIMEOUT); 2681606a214SLin Jinhan 2691606a214SLin Jinhan reg_ctrl = 0; 270b353a43cSLin Jinhan tmp_ctx->algo = algo; 271b353a43cSLin Jinhan switch (algo) { 272b353a43cSLin Jinhan case CRYPTO_MD5: 27349a2135eSLin Jinhan case CRYPTO_HMAC_MD5: 274b353a43cSLin Jinhan reg_ctrl |= CRYPTO_MODE_MD5; 275b353a43cSLin Jinhan tmp_ctx->digest_size = 16; 276b353a43cSLin Jinhan break; 277b353a43cSLin Jinhan case CRYPTO_SHA1: 27849a2135eSLin Jinhan case CRYPTO_HMAC_SHA1: 279b353a43cSLin Jinhan reg_ctrl |= CRYPTO_MODE_SHA1; 280b353a43cSLin Jinhan tmp_ctx->digest_size = 20; 281b353a43cSLin Jinhan break; 282b353a43cSLin Jinhan case CRYPTO_SHA256: 28349a2135eSLin Jinhan case CRYPTO_HMAC_SHA256: 284b353a43cSLin Jinhan reg_ctrl |= CRYPTO_MODE_SHA256; 285b353a43cSLin Jinhan tmp_ctx->digest_size = 32; 286b353a43cSLin Jinhan break; 287e7846385SLin Jinhan case CRYPTO_SHA512: 28849a2135eSLin Jinhan case CRYPTO_HMAC_SHA512: 289e7846385SLin Jinhan reg_ctrl |= CRYPTO_MODE_SHA512; 290e7846385SLin Jinhan tmp_ctx->digest_size = 64; 291e7846385SLin Jinhan break; 29249a2135eSLin Jinhan case CRYPTO_SM3: 29349a2135eSLin Jinhan case CRYPTO_HMAC_SM3: 29449a2135eSLin Jinhan reg_ctrl |= CRYPTO_MODE_SM3; 29549a2135eSLin Jinhan tmp_ctx->digest_size = 32; 29649a2135eSLin Jinhan break; 297b353a43cSLin Jinhan default: 298b353a43cSLin Jinhan ret = -EINVAL; 299b353a43cSLin Jinhan goto exit; 300b353a43cSLin Jinhan } 301b353a43cSLin Jinhan 302b353a43cSLin Jinhan clear_hash_out_reg(); 303b353a43cSLin Jinhan 304b353a43cSLin Jinhan /* enable hardware padding */ 305b353a43cSLin Jinhan reg_ctrl |= CRYPTO_HW_PAD_ENABLE; 306b353a43cSLin Jinhan crypto_write(reg_ctrl | CRYPTO_WRITE_MASK_ALL, CRYPTO_HASH_CTL); 307b353a43cSLin Jinhan 308b353a43cSLin Jinhan /* FIFO input and output data byte swap */ 309b353a43cSLin Jinhan /* such as B0, B1, B2, B3 -> B3, B2, B1, B0 */ 310b353a43cSLin Jinhan reg_ctrl = CRYPTO_DOUT_BYTESWAP | CRYPTO_DOIN_BYTESWAP; 311b353a43cSLin Jinhan crypto_write(reg_ctrl | CRYPTO_WRITE_MASK_ALL, CRYPTO_FIFO_CTL); 312b353a43cSLin Jinhan 3131606a214SLin Jinhan /* enable src_item_done interrupt */ 3141606a214SLin Jinhan crypto_write(CRYPTO_SRC_ITEM_INT_EN, CRYPTO_DMA_INT_EN); 315b353a43cSLin Jinhan 316b353a43cSLin Jinhan tmp_ctx->magic = RK_HASH_CTX_MAGIC; 317b353a43cSLin Jinhan 318b353a43cSLin Jinhan return 0; 319b353a43cSLin Jinhan exit: 320b353a43cSLin Jinhan /* clear hash setting if init failed */ 321b353a43cSLin Jinhan crypto_write(CRYPTO_WRITE_MASK_ALL | 0, CRYPTO_HASH_CTL); 322b353a43cSLin Jinhan 323b353a43cSLin Jinhan return ret; 324b353a43cSLin Jinhan } 325b353a43cSLin Jinhan 326c48f1acfSLin Jinhan static int rk_hash_direct_calc(void *hw_data, const u8 *data, 3271606a214SLin Jinhan u32 data_len, u8 *started_flag, u8 is_last) 328b353a43cSLin Jinhan { 329c48f1acfSLin Jinhan struct rockchip_crypto_priv *priv = hw_data; 330c48f1acfSLin Jinhan struct rk_hash_ctx *hash_ctx = priv->hw_ctx; 331c48f1acfSLin Jinhan struct crypto_lli_desc *lli = &hash_ctx->data_lli; 332b353a43cSLin Jinhan int ret = -EINVAL; 33300fa57d8SLin Jinhan u32 tmp = 0, mask = 0; 334b353a43cSLin Jinhan 33549a2135eSLin Jinhan assert(IS_ALIGNED((ulong)data, DATA_ADDR_ALIGN_SIZE)); 33649a2135eSLin Jinhan assert(is_last || IS_ALIGNED(data_len, DATA_LEN_ALIGN_SIZE)); 337b353a43cSLin Jinhan 3381606a214SLin Jinhan debug("%s: data = %p, len = %u, s = %x, l = %x\n", 3391606a214SLin Jinhan __func__, data, data_len, *started_flag, is_last); 340b353a43cSLin Jinhan 3411606a214SLin Jinhan memset(lli, 0x00, sizeof(*lli)); 3421606a214SLin Jinhan lli->src_addr = (u32)virt_to_phys(data); 3431606a214SLin Jinhan lli->src_len = data_len; 3441606a214SLin Jinhan lli->dma_ctrl = LLI_DMA_CTRL_SRC_DONE; 345b353a43cSLin Jinhan 3461606a214SLin Jinhan if (is_last) { 3471606a214SLin Jinhan lli->user_define |= LLI_USER_STRING_LAST; 3481606a214SLin Jinhan lli->dma_ctrl |= LLI_DMA_CTRL_LAST; 349b353a43cSLin Jinhan } else { 3501606a214SLin Jinhan lli->next_addr = (u32)virt_to_phys(lli); 3511606a214SLin Jinhan lli->dma_ctrl |= LLI_DMA_CTRL_PAUSE; 3521606a214SLin Jinhan } 3531606a214SLin Jinhan 3541606a214SLin Jinhan if (!(*started_flag)) { 3551606a214SLin Jinhan lli->user_define |= 3561606a214SLin Jinhan (LLI_USER_STRING_START | LLI_USER_CPIHER_START); 3571606a214SLin Jinhan crypto_write((u32)virt_to_phys(lli), CRYPTO_DMA_LLI_ADDR); 3581606a214SLin Jinhan crypto_write((CRYPTO_HASH_ENABLE << CRYPTO_WRITE_MASK_SHIFT) | 3591606a214SLin Jinhan CRYPTO_HASH_ENABLE, CRYPTO_HASH_CTL); 3601606a214SLin Jinhan tmp = CRYPTO_DMA_START; 3611606a214SLin Jinhan *started_flag = 1; 3621606a214SLin Jinhan } else { 363b353a43cSLin Jinhan tmp = CRYPTO_DMA_RESTART; 364b353a43cSLin Jinhan } 365b353a43cSLin Jinhan 366b353a43cSLin Jinhan /* flush cache */ 367c48f1acfSLin Jinhan crypto_flush_cacheline((ulong)lli, sizeof(*lli)); 368c48f1acfSLin Jinhan crypto_flush_cacheline((ulong)data, data_len); 369b353a43cSLin Jinhan 370b353a43cSLin Jinhan /* start calculate */ 371b353a43cSLin Jinhan crypto_write(tmp << CRYPTO_WRITE_MASK_SHIFT | tmp, 372b353a43cSLin Jinhan CRYPTO_DMA_CTL); 373b353a43cSLin Jinhan 37400fa57d8SLin Jinhan /* mask CRYPTO_SYNC_LOCKSTEP_INT_ST flag */ 37500fa57d8SLin Jinhan mask = ~(mask | CRYPTO_SYNC_LOCKSTEP_INT_ST); 37600fa57d8SLin Jinhan 377b353a43cSLin Jinhan /* wait calc ok */ 37849a2135eSLin Jinhan ret = RK_POLL_TIMEOUT(!(crypto_read(CRYPTO_DMA_INT_ST) & mask), 37949a2135eSLin Jinhan RK_CRYPTO_TIMEOUT); 380b353a43cSLin Jinhan 381b353a43cSLin Jinhan /* clear interrupt status */ 382b353a43cSLin Jinhan tmp = crypto_read(CRYPTO_DMA_INT_ST); 383b353a43cSLin Jinhan crypto_write(tmp, CRYPTO_DMA_INT_ST); 384b353a43cSLin Jinhan 385b353a43cSLin Jinhan if (tmp != CRYPTO_SRC_ITEM_DONE_INT_ST && 386b353a43cSLin Jinhan tmp != CRYPTO_ZERO_LEN_INT_ST) { 3871606a214SLin Jinhan debug("[%s] %d: CRYPTO_DMA_INT_ST = 0x%x\n", 388b353a43cSLin Jinhan __func__, __LINE__, tmp); 3891606a214SLin Jinhan goto exit; 390b353a43cSLin Jinhan } 391b353a43cSLin Jinhan 392c48f1acfSLin Jinhan priv->length += data_len; 3931606a214SLin Jinhan exit: 3941606a214SLin Jinhan return ret; 395b353a43cSLin Jinhan } 3961606a214SLin Jinhan 3971606a214SLin Jinhan int rk_hash_update(void *ctx, const u8 *data, u32 data_len) 3981606a214SLin Jinhan { 3991606a214SLin Jinhan struct rk_hash_ctx *tmp_ctx = (struct rk_hash_ctx *)ctx; 400c48f1acfSLin Jinhan int ret = -EINVAL; 4011606a214SLin Jinhan 4021606a214SLin Jinhan debug("\n"); 4031606a214SLin Jinhan if (!tmp_ctx || !data) 404c48f1acfSLin Jinhan goto exit; 4051606a214SLin Jinhan 4061606a214SLin Jinhan if (tmp_ctx->digest_size == 0 || tmp_ctx->magic != RK_HASH_CTX_MAGIC) 407c48f1acfSLin Jinhan goto exit; 4081606a214SLin Jinhan 409c48f1acfSLin Jinhan ret = crypto_hash_update_with_cache(tmp_ctx->hash_cache, 410c48f1acfSLin Jinhan data, data_len); 4111606a214SLin Jinhan 412c48f1acfSLin Jinhan exit: 413b353a43cSLin Jinhan /* free lli list */ 414c48f1acfSLin Jinhan if (ret) 415b353a43cSLin Jinhan hw_hash_clean_ctx(tmp_ctx); 416b353a43cSLin Jinhan 417c48f1acfSLin Jinhan return ret; 418b353a43cSLin Jinhan } 419b353a43cSLin Jinhan 420b353a43cSLin Jinhan int rk_hash_final(void *ctx, u8 *digest, size_t len) 421b353a43cSLin Jinhan { 422b353a43cSLin Jinhan struct rk_hash_ctx *tmp_ctx = (struct rk_hash_ctx *)ctx; 423b353a43cSLin Jinhan int ret = -EINVAL; 424b353a43cSLin Jinhan 425b353a43cSLin Jinhan if (!digest) 426b353a43cSLin Jinhan goto exit; 427b353a43cSLin Jinhan 428b353a43cSLin Jinhan if (!tmp_ctx || 429b353a43cSLin Jinhan tmp_ctx->digest_size == 0 || 430b353a43cSLin Jinhan len > tmp_ctx->digest_size || 431b353a43cSLin Jinhan tmp_ctx->magic != RK_HASH_CTX_MAGIC) { 432b353a43cSLin Jinhan goto exit; 433b353a43cSLin Jinhan } 434b353a43cSLin Jinhan 435b353a43cSLin Jinhan /* wait hash value ok */ 43649a2135eSLin Jinhan ret = RK_POLL_TIMEOUT(!crypto_read(CRYPTO_HASH_VALID), 43749a2135eSLin Jinhan RK_CRYPTO_TIMEOUT); 438b353a43cSLin Jinhan 439c3ce9937SLin Jinhan read_regs(CRYPTO_HASH_DOUT_0, digest, len); 440b353a43cSLin Jinhan 441b353a43cSLin Jinhan /* clear hash status */ 442b353a43cSLin Jinhan crypto_write(CRYPTO_HASH_IS_VALID, CRYPTO_HASH_VALID); 443b353a43cSLin Jinhan crypto_write(CRYPTO_WRITE_MASK_ALL | 0, CRYPTO_HASH_CTL); 444b353a43cSLin Jinhan 445b353a43cSLin Jinhan exit: 446b353a43cSLin Jinhan 447b353a43cSLin Jinhan return ret; 448b353a43cSLin Jinhan } 449b353a43cSLin Jinhan 450b353a43cSLin Jinhan static u32 rockchip_crypto_capability(struct udevice *dev) 451b353a43cSLin Jinhan { 45249a2135eSLin Jinhan struct rockchip_crypto_priv *priv = dev_get_priv(dev); 45349a2135eSLin Jinhan u32 capability, mask = 0; 4547eea1823SLin Jinhan 45549a2135eSLin Jinhan capability = priv->soc_data->capability; 45649a2135eSLin Jinhan 45749a2135eSLin Jinhan #if !(CONFIG_IS_ENABLED(ROCKCHIP_CIPHER)) 45849a2135eSLin Jinhan mask |= (CRYPTO_DES | CRYPTO_AES | CRYPTO_SM4); 459c0e47d03SLin Jinhan #endif 4607eea1823SLin Jinhan 46149a2135eSLin Jinhan #if !(CONFIG_IS_ENABLED(ROCKCHIP_HMAC)) 46249a2135eSLin Jinhan mask |= (CRYPTO_HMAC_MD5 | CRYPTO_HMAC_SHA1 | CRYPTO_HMAC_SHA256 | 46349a2135eSLin Jinhan CRYPTO_HMAC_SHA512 | CRYPTO_HMAC_SM3); 46449a2135eSLin Jinhan #endif 46549a2135eSLin Jinhan 46649a2135eSLin Jinhan #if !(CONFIG_IS_ENABLED(ROCKCHIP_RSA)) 46749a2135eSLin Jinhan mask |= (CRYPTO_RSA512 | CRYPTO_RSA1024 | CRYPTO_RSA2048 | 46849a2135eSLin Jinhan CRYPTO_RSA3072 | CRYPTO_RSA4096); 46949a2135eSLin Jinhan #endif 47049a2135eSLin Jinhan 47149a2135eSLin Jinhan return capability & (~mask); 472b353a43cSLin Jinhan } 473b353a43cSLin Jinhan 474b353a43cSLin Jinhan static int rockchip_crypto_sha_init(struct udevice *dev, sha_context *ctx) 475b353a43cSLin Jinhan { 476b353a43cSLin Jinhan struct rockchip_crypto_priv *priv = dev_get_priv(dev); 477c48f1acfSLin Jinhan struct rk_hash_ctx *hash_ctx = priv->hw_ctx; 478b353a43cSLin Jinhan 479b353a43cSLin Jinhan if (!ctx) 480b353a43cSLin Jinhan return -EINVAL; 481b353a43cSLin Jinhan 482c48f1acfSLin Jinhan memset(hash_ctx, 0x00, sizeof(*hash_ctx)); 483b353a43cSLin Jinhan 484c48f1acfSLin Jinhan priv->length = 0; 485c48f1acfSLin Jinhan 486c48f1acfSLin Jinhan hash_ctx->hash_cache = crypto_hash_cache_alloc(rk_hash_direct_calc, 487c48f1acfSLin Jinhan priv, ctx->length, 48849a2135eSLin Jinhan DATA_ADDR_ALIGN_SIZE, 48949a2135eSLin Jinhan DATA_LEN_ALIGN_SIZE); 490c48f1acfSLin Jinhan if (!hash_ctx->hash_cache) 491c48f1acfSLin Jinhan return -EFAULT; 492c48f1acfSLin Jinhan 493c48f1acfSLin Jinhan return rk_hash_init(hash_ctx, ctx->algo); 494b353a43cSLin Jinhan } 495b353a43cSLin Jinhan 496b353a43cSLin Jinhan static int rockchip_crypto_sha_update(struct udevice *dev, 497b353a43cSLin Jinhan u32 *input, u32 len) 498b353a43cSLin Jinhan { 499b353a43cSLin Jinhan struct rockchip_crypto_priv *priv = dev_get_priv(dev); 500086e8fa8SLin Jinhan int ret, i; 501086e8fa8SLin Jinhan u8 *p; 502b353a43cSLin Jinhan 503b353a43cSLin Jinhan if (!len) 504b353a43cSLin Jinhan return -EINVAL; 505b353a43cSLin Jinhan 506086e8fa8SLin Jinhan p = (u8 *)input; 507086e8fa8SLin Jinhan 508086e8fa8SLin Jinhan for (i = 0; i < len / HASH_UPDATE_LIMIT; i++, p += HASH_UPDATE_LIMIT) { 509086e8fa8SLin Jinhan ret = rk_hash_update(priv->hw_ctx, p, HASH_UPDATE_LIMIT); 510086e8fa8SLin Jinhan if (ret) 511086e8fa8SLin Jinhan goto exit; 512086e8fa8SLin Jinhan } 513086e8fa8SLin Jinhan 514086e8fa8SLin Jinhan if (len % HASH_UPDATE_LIMIT) 515086e8fa8SLin Jinhan ret = rk_hash_update(priv->hw_ctx, p, len % HASH_UPDATE_LIMIT); 516086e8fa8SLin Jinhan 517086e8fa8SLin Jinhan exit: 518086e8fa8SLin Jinhan return ret; 519b353a43cSLin Jinhan } 520b353a43cSLin Jinhan 521b353a43cSLin Jinhan static int rockchip_crypto_sha_final(struct udevice *dev, 522b353a43cSLin Jinhan sha_context *ctx, u8 *output) 523b353a43cSLin Jinhan { 524b353a43cSLin Jinhan struct rockchip_crypto_priv *priv = dev_get_priv(dev); 525b353a43cSLin Jinhan u32 nbits; 526c48f1acfSLin Jinhan int ret; 527b353a43cSLin Jinhan 528b353a43cSLin Jinhan nbits = crypto_algo_nbits(ctx->algo); 529b353a43cSLin Jinhan 530c48f1acfSLin Jinhan if (priv->length != ctx->length) { 531c48f1acfSLin Jinhan printf("total length(0x%08x) != init length(0x%08x)!\n", 532c48f1acfSLin Jinhan priv->length, ctx->length); 533c48f1acfSLin Jinhan ret = -EIO; 534c48f1acfSLin Jinhan goto exit; 535c48f1acfSLin Jinhan } 536c48f1acfSLin Jinhan 537c48f1acfSLin Jinhan ret = rk_hash_final(priv->hw_ctx, (u8 *)output, BITS2BYTE(nbits)); 538c48f1acfSLin Jinhan 539c48f1acfSLin Jinhan exit: 540c48f1acfSLin Jinhan hw_hash_clean_ctx(priv->hw_ctx); 541c48f1acfSLin Jinhan return ret; 542b353a43cSLin Jinhan } 543b353a43cSLin Jinhan 54449a2135eSLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_HMAC) 54549a2135eSLin Jinhan int rk_hmac_init(void *hw_ctx, u32 algo, u8 *key, u32 key_len) 54649a2135eSLin Jinhan { 54749a2135eSLin Jinhan u32 reg_ctrl = 0; 54849a2135eSLin Jinhan int ret; 54949a2135eSLin Jinhan 55049a2135eSLin Jinhan if (!key || !key_len || key_len > 64) 55149a2135eSLin Jinhan return -EINVAL; 55249a2135eSLin Jinhan 55349a2135eSLin Jinhan clear_key_regs(); 55449a2135eSLin Jinhan 55549a2135eSLin Jinhan write_key_reg(0, key, key_len); 55649a2135eSLin Jinhan 55749a2135eSLin Jinhan ret = rk_hash_init(hw_ctx, algo); 55849a2135eSLin Jinhan if (ret) 55949a2135eSLin Jinhan return ret; 56049a2135eSLin Jinhan 56149a2135eSLin Jinhan reg_ctrl = crypto_read(CRYPTO_HASH_CTL) | CRYPTO_HMAC_ENABLE; 56249a2135eSLin Jinhan crypto_write(reg_ctrl | CRYPTO_WRITE_MASK_ALL, CRYPTO_HASH_CTL); 56349a2135eSLin Jinhan 56449a2135eSLin Jinhan return ret; 56549a2135eSLin Jinhan } 56649a2135eSLin Jinhan 56749a2135eSLin Jinhan static int rockchip_crypto_hmac_init(struct udevice *dev, 56849a2135eSLin Jinhan sha_context *ctx, u8 *key, u32 key_len) 56949a2135eSLin Jinhan { 57049a2135eSLin Jinhan struct rockchip_crypto_priv *priv = dev_get_priv(dev); 57149a2135eSLin Jinhan struct rk_hash_ctx *hash_ctx = priv->hw_ctx; 57249a2135eSLin Jinhan 57349a2135eSLin Jinhan if (!ctx) 57449a2135eSLin Jinhan return -EINVAL; 57549a2135eSLin Jinhan 57649a2135eSLin Jinhan memset(hash_ctx, 0x00, sizeof(*hash_ctx)); 57749a2135eSLin Jinhan 57849a2135eSLin Jinhan priv->length = 0; 57949a2135eSLin Jinhan 58049a2135eSLin Jinhan hash_ctx->hash_cache = crypto_hash_cache_alloc(rk_hash_direct_calc, 58149a2135eSLin Jinhan priv, ctx->length, 58249a2135eSLin Jinhan DATA_ADDR_ALIGN_SIZE, 58349a2135eSLin Jinhan DATA_LEN_ALIGN_SIZE); 58449a2135eSLin Jinhan if (!hash_ctx->hash_cache) 58549a2135eSLin Jinhan return -EFAULT; 58649a2135eSLin Jinhan 58749a2135eSLin Jinhan return rk_hmac_init(priv->hw_ctx, ctx->algo, key, key_len); 58849a2135eSLin Jinhan } 58949a2135eSLin Jinhan 59049a2135eSLin Jinhan static int rockchip_crypto_hmac_update(struct udevice *dev, 59149a2135eSLin Jinhan u32 *input, u32 len) 59249a2135eSLin Jinhan { 59349a2135eSLin Jinhan return rockchip_crypto_sha_update(dev, input, len); 59449a2135eSLin Jinhan } 59549a2135eSLin Jinhan 59649a2135eSLin Jinhan static int rockchip_crypto_hmac_final(struct udevice *dev, 59749a2135eSLin Jinhan sha_context *ctx, u8 *output) 59849a2135eSLin Jinhan { 59949a2135eSLin Jinhan return rockchip_crypto_sha_final(dev, ctx, output); 60049a2135eSLin Jinhan } 60149a2135eSLin Jinhan 60249a2135eSLin Jinhan #endif 60349a2135eSLin Jinhan 60449a2135eSLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_CIPHER) 60549a2135eSLin Jinhan static u8 g_key_chn; 60649a2135eSLin Jinhan 60749a2135eSLin Jinhan static const u32 rk_mode2bc_mode[RK_MODE_MAX] = { 60849a2135eSLin Jinhan [RK_MODE_ECB] = CRYPTO_BC_ECB, 60949a2135eSLin Jinhan [RK_MODE_CBC] = CRYPTO_BC_CBC, 61049a2135eSLin Jinhan [RK_MODE_CTS] = CRYPTO_BC_CTS, 61149a2135eSLin Jinhan [RK_MODE_CTR] = CRYPTO_BC_CTR, 61249a2135eSLin Jinhan [RK_MODE_CFB] = CRYPTO_BC_CFB, 61349a2135eSLin Jinhan [RK_MODE_OFB] = CRYPTO_BC_OFB, 61449a2135eSLin Jinhan [RK_MODE_XTS] = CRYPTO_BC_XTS, 615c3ce9937SLin Jinhan [RK_MODE_CCM] = CRYPTO_BC_CCM, 616c3ce9937SLin Jinhan [RK_MODE_GCM] = CRYPTO_BC_GCM, 617d9332f1cSLin Jinhan [RK_MODE_CMAC] = CRYPTO_BC_CMAC, 618d9332f1cSLin Jinhan [RK_MODE_CBC_MAC] = CRYPTO_BC_CBC_MAC, 61949a2135eSLin Jinhan }; 62049a2135eSLin Jinhan 621c3ce9937SLin Jinhan static inline void set_pc_len_reg(u32 chn, u64 pc_len) 622c3ce9937SLin Jinhan { 623c3ce9937SLin Jinhan u32 chn_base = CRYPTO_CH0_PC_LEN_0 + chn * 0x08; 624c3ce9937SLin Jinhan 625c3ce9937SLin Jinhan crypto_write(pc_len & 0xffffffff, chn_base); 626c3ce9937SLin Jinhan crypto_write(pc_len >> 32, chn_base + 4); 627c3ce9937SLin Jinhan } 628c3ce9937SLin Jinhan 629c3ce9937SLin Jinhan static inline void set_aad_len_reg(u32 chn, u64 pc_len) 630c3ce9937SLin Jinhan { 631c3ce9937SLin Jinhan u32 chn_base = CRYPTO_CH0_AAD_LEN_0 + chn * 0x08; 632c3ce9937SLin Jinhan 633c3ce9937SLin Jinhan crypto_write(pc_len & 0xffffffff, chn_base); 634c3ce9937SLin Jinhan crypto_write(pc_len >> 32, chn_base + 4); 635c3ce9937SLin Jinhan } 636c3ce9937SLin Jinhan 63749a2135eSLin Jinhan static inline bool is_des_mode(u32 rk_mode) 63849a2135eSLin Jinhan { 63949a2135eSLin Jinhan return (rk_mode == RK_MODE_ECB || 64049a2135eSLin Jinhan rk_mode == RK_MODE_CBC || 64149a2135eSLin Jinhan rk_mode == RK_MODE_CFB || 64249a2135eSLin Jinhan rk_mode == RK_MODE_OFB); 64349a2135eSLin Jinhan } 64449a2135eSLin Jinhan 6456b53126aSLin Jinhan static void dump_crypto_state(struct crypto_lli_desc *desc, 6466b53126aSLin Jinhan u32 tmp, u32 expt_int, 6476b53126aSLin Jinhan const u8 *in, const u8 *out, 6486b53126aSLin Jinhan u32 len, int ret) 64949a2135eSLin Jinhan { 65049a2135eSLin Jinhan IMSG("%s\n", ret == -ETIME ? "timeout" : "dismatch"); 65149a2135eSLin Jinhan 65249a2135eSLin Jinhan IMSG("CRYPTO_DMA_INT_ST = %08x, expect_int = %08x\n", 65349a2135eSLin Jinhan tmp, expt_int); 65449a2135eSLin Jinhan IMSG("data desc = %p\n", desc); 65549a2135eSLin Jinhan IMSG("\taddr_in = [%08x <=> %08x]\n", 65649a2135eSLin Jinhan desc->src_addr, (u32)virt_to_phys(in)); 65749a2135eSLin Jinhan IMSG("\taddr_out = [%08x <=> %08x]\n", 65849a2135eSLin Jinhan desc->dst_addr, (u32)virt_to_phys(out)); 65949a2135eSLin Jinhan IMSG("\tsrc_len = [%08x <=> %08x]\n", 66049a2135eSLin Jinhan desc->src_len, (u32)len); 66149a2135eSLin Jinhan IMSG("\tdst_len = %08x\n", desc->dst_len); 66249a2135eSLin Jinhan IMSG("\tdma_ctl = %08x\n", desc->dma_ctrl); 66349a2135eSLin Jinhan IMSG("\tuser_define = %08x\n", desc->user_define); 66449a2135eSLin Jinhan 66549a2135eSLin Jinhan IMSG("\n\nDMA CRYPTO_DMA_LLI_ADDR status = %08x\n", 66649a2135eSLin Jinhan crypto_read(CRYPTO_DMA_LLI_ADDR)); 66749a2135eSLin Jinhan IMSG("DMA CRYPTO_DMA_ST status = %08x\n", 66849a2135eSLin Jinhan crypto_read(CRYPTO_DMA_ST)); 66949a2135eSLin Jinhan IMSG("DMA CRYPTO_DMA_STATE status = %08x\n", 67049a2135eSLin Jinhan crypto_read(CRYPTO_DMA_STATE)); 67149a2135eSLin Jinhan IMSG("DMA CRYPTO_DMA_LLI_RADDR status = %08x\n", 67249a2135eSLin Jinhan crypto_read(CRYPTO_DMA_LLI_RADDR)); 67349a2135eSLin Jinhan IMSG("DMA CRYPTO_DMA_SRC_RADDR status = %08x\n", 67449a2135eSLin Jinhan crypto_read(CRYPTO_DMA_SRC_RADDR)); 67549a2135eSLin Jinhan IMSG("DMA CRYPTO_DMA_DST_RADDR status = %08x\n", 67649a2135eSLin Jinhan crypto_read(CRYPTO_DMA_DST_RADDR)); 67749a2135eSLin Jinhan IMSG("DMA CRYPTO_CIPHER_ST status = %08x\n", 67849a2135eSLin Jinhan crypto_read(CRYPTO_CIPHER_ST)); 67949a2135eSLin Jinhan IMSG("DMA CRYPTO_CIPHER_STATE status = %08x\n", 68049a2135eSLin Jinhan crypto_read(CRYPTO_CIPHER_STATE)); 68149a2135eSLin Jinhan IMSG("DMA CRYPTO_TAG_VALID status = %08x\n", 68249a2135eSLin Jinhan crypto_read(CRYPTO_TAG_VALID)); 68349a2135eSLin Jinhan IMSG("LOCKSTEP status = %08x\n\n", 68449a2135eSLin Jinhan crypto_read(0x618)); 68549a2135eSLin Jinhan 68649a2135eSLin Jinhan IMSG("dst %dbyte not transferred\n", 68749a2135eSLin Jinhan desc->dst_addr + desc->dst_len - 68849a2135eSLin Jinhan crypto_read(CRYPTO_DMA_DST_RADDR)); 68949a2135eSLin Jinhan } 69049a2135eSLin Jinhan 691c3ce9937SLin Jinhan static int ccm128_set_iv_reg(u32 chn, const u8 *nonce, u32 nlen) 692c3ce9937SLin Jinhan { 693c3ce9937SLin Jinhan u8 iv_buf[AES_BLOCK_SIZE]; 694c3ce9937SLin Jinhan u32 L; 695c3ce9937SLin Jinhan 696c3ce9937SLin Jinhan memset(iv_buf, 0x00, sizeof(iv_buf)); 697c3ce9937SLin Jinhan 698c3ce9937SLin Jinhan L = 15 - nlen; 699c3ce9937SLin Jinhan iv_buf[0] = ((u8)(L - 1) & 7); 700c3ce9937SLin Jinhan 701c3ce9937SLin Jinhan /* the L parameter */ 702c3ce9937SLin Jinhan L = iv_buf[0] & 7; 703c3ce9937SLin Jinhan 704c3ce9937SLin Jinhan /* nonce is too short */ 705c3ce9937SLin Jinhan if (nlen < (14 - L)) 706c3ce9937SLin Jinhan return -EINVAL; 707c3ce9937SLin Jinhan 708c3ce9937SLin Jinhan /* clear aad flag */ 709c3ce9937SLin Jinhan iv_buf[0] &= ~0x40; 710c3ce9937SLin Jinhan memcpy(&iv_buf[1], nonce, 14 - L); 711c3ce9937SLin Jinhan 712c3ce9937SLin Jinhan set_iv_reg(chn, iv_buf, AES_BLOCK_SIZE); 713c3ce9937SLin Jinhan 714c3ce9937SLin Jinhan return 0; 715c3ce9937SLin Jinhan } 716c3ce9937SLin Jinhan 717c3ce9937SLin Jinhan static void ccm_aad_padding(u32 aad_len, u8 *padding, u32 *padding_size) 718c3ce9937SLin Jinhan { 719c3ce9937SLin Jinhan u32 i; 720c3ce9937SLin Jinhan 721c3ce9937SLin Jinhan i = aad_len < (0x10000 - 0x100) ? 2 : 6; 722c3ce9937SLin Jinhan 723c3ce9937SLin Jinhan if (i == 2) { 724c3ce9937SLin Jinhan padding[0] = (u8)(aad_len >> 8); 725c3ce9937SLin Jinhan padding[1] = (u8)aad_len; 726c3ce9937SLin Jinhan } else { 727c3ce9937SLin Jinhan padding[0] = 0xFF; 728c3ce9937SLin Jinhan padding[1] = 0xFE; 729c3ce9937SLin Jinhan padding[2] = (u8)(aad_len >> 24); 730c3ce9937SLin Jinhan padding[3] = (u8)(aad_len >> 16); 731c3ce9937SLin Jinhan padding[4] = (u8)(aad_len >> 8); 732c3ce9937SLin Jinhan } 733c3ce9937SLin Jinhan 734c3ce9937SLin Jinhan *padding_size = i; 735c3ce9937SLin Jinhan } 736c3ce9937SLin Jinhan 737c3ce9937SLin Jinhan static int ccm_compose_aad_iv(u8 *aad_iv, u32 data_len, u32 tag_size) 738c3ce9937SLin Jinhan { 739c3ce9937SLin Jinhan aad_iv[0] |= ((u8)(((tag_size - 2) / 2) & 7) << 3); 740c3ce9937SLin Jinhan 741c3ce9937SLin Jinhan aad_iv[12] = (u8)(data_len >> 24); 742c3ce9937SLin Jinhan aad_iv[13] = (u8)(data_len >> 16); 743c3ce9937SLin Jinhan aad_iv[14] = (u8)(data_len >> 8); 744c3ce9937SLin Jinhan aad_iv[15] = (u8)data_len; 745c3ce9937SLin Jinhan 746c3ce9937SLin Jinhan aad_iv[0] |= 0x40; //set aad flag 747c3ce9937SLin Jinhan 748c3ce9937SLin Jinhan return 0; 749c3ce9937SLin Jinhan } 750c3ce9937SLin Jinhan 75149a2135eSLin Jinhan static int hw_cipher_init(u32 chn, const u8 *key, const u8 *twk_key, 75249a2135eSLin Jinhan u32 key_len, const u8 *iv, u32 iv_len, 75349a2135eSLin Jinhan u32 algo, u32 mode, bool enc) 75449a2135eSLin Jinhan { 75549a2135eSLin Jinhan u32 rk_mode = RK_GET_RK_MODE(mode); 75649a2135eSLin Jinhan u32 key_chn_sel = chn; 75749a2135eSLin Jinhan u32 reg_ctrl = 0; 75849a2135eSLin Jinhan 75949a2135eSLin Jinhan IMSG("%s: key addr is %p, key_len is %d, iv addr is %p", 76049a2135eSLin Jinhan __func__, key, key_len, iv); 76149a2135eSLin Jinhan if (rk_mode >= RK_MODE_MAX) 76249a2135eSLin Jinhan return -EINVAL; 76349a2135eSLin Jinhan 76449a2135eSLin Jinhan switch (algo) { 76549a2135eSLin Jinhan case CRYPTO_DES: 76649a2135eSLin Jinhan if (key_len > DES_BLOCK_SIZE) 76749a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_TDES; 76849a2135eSLin Jinhan else 76949a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_DES; 77049a2135eSLin Jinhan break; 77149a2135eSLin Jinhan case CRYPTO_AES: 77249a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_AES; 77349a2135eSLin Jinhan break; 77449a2135eSLin Jinhan case CRYPTO_SM4: 77549a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_SM4; 77649a2135eSLin Jinhan break; 77749a2135eSLin Jinhan default: 77849a2135eSLin Jinhan return -EINVAL; 77949a2135eSLin Jinhan } 78049a2135eSLin Jinhan 78149a2135eSLin Jinhan if (algo == CRYPTO_AES || algo == CRYPTO_SM4) { 78249a2135eSLin Jinhan switch (key_len) { 78349a2135eSLin Jinhan case AES_KEYSIZE_128: 78449a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_128_bit_key; 78549a2135eSLin Jinhan break; 78649a2135eSLin Jinhan case AES_KEYSIZE_192: 78749a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_192_bit_key; 78849a2135eSLin Jinhan break; 78949a2135eSLin Jinhan case AES_KEYSIZE_256: 79049a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_256_bit_key; 79149a2135eSLin Jinhan break; 79249a2135eSLin Jinhan default: 79349a2135eSLin Jinhan return -EINVAL; 79449a2135eSLin Jinhan } 79549a2135eSLin Jinhan } 79649a2135eSLin Jinhan 79749a2135eSLin Jinhan reg_ctrl |= rk_mode2bc_mode[rk_mode]; 79849a2135eSLin Jinhan if (!enc) 79949a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_DECRYPT; 80049a2135eSLin Jinhan 80149a2135eSLin Jinhan /* write key data to reg */ 80249a2135eSLin Jinhan write_key_reg(key_chn_sel, key, key_len); 80349a2135eSLin Jinhan 80449a2135eSLin Jinhan /* write twk key for xts mode */ 80549a2135eSLin Jinhan if (rk_mode == RK_MODE_XTS) 80649a2135eSLin Jinhan write_key_reg(key_chn_sel + 4, twk_key, key_len); 80749a2135eSLin Jinhan 80849a2135eSLin Jinhan /* set iv reg */ 809c3ce9937SLin Jinhan if (rk_mode == RK_MODE_CCM) 810c3ce9937SLin Jinhan ccm128_set_iv_reg(chn, iv, iv_len); 811c3ce9937SLin Jinhan else 81249a2135eSLin Jinhan set_iv_reg(chn, iv, iv_len); 81349a2135eSLin Jinhan 81449a2135eSLin Jinhan /* din_swap set 1, dout_swap set 1, default 1. */ 81549a2135eSLin Jinhan crypto_write(0x00030003, CRYPTO_FIFO_CTL); 81649a2135eSLin Jinhan crypto_write(CRYPTO_LIST_DONE_INT_EN | CRYPTO_DST_ITEM_DONE_INT_EN, 81749a2135eSLin Jinhan CRYPTO_DMA_INT_EN); 81849a2135eSLin Jinhan 81949a2135eSLin Jinhan crypto_write(reg_ctrl | CRYPTO_WRITE_MASK_ALL, CRYPTO_BC_CTL); 82049a2135eSLin Jinhan 82149a2135eSLin Jinhan return 0; 82249a2135eSLin Jinhan } 82349a2135eSLin Jinhan 82449a2135eSLin Jinhan static int hw_cipher_crypt(const u8 *in, u8 *out, u64 len, 825c3ce9937SLin Jinhan const u8 *aad, u32 aad_len, 826c3ce9937SLin Jinhan u8 *tag, u32 tag_len, u32 mode) 82749a2135eSLin Jinhan { 828c3ce9937SLin Jinhan struct crypto_lli_desc *data_desc = NULL, *aad_desc = NULL; 829c3ce9937SLin Jinhan u8 *dma_in = NULL, *dma_out = NULL, *aad_tmp = NULL; 83049a2135eSLin Jinhan u32 rk_mode = RK_GET_RK_MODE(mode); 83149a2135eSLin Jinhan u32 reg_ctrl = 0, tmp_len = 0; 83249a2135eSLin Jinhan u32 expt_int = 0, mask = 0; 83349a2135eSLin Jinhan u32 key_chn = g_key_chn; 83449a2135eSLin Jinhan u32 tmp, dst_len = 0; 83549a2135eSLin Jinhan int ret = -1; 83649a2135eSLin Jinhan 83749a2135eSLin Jinhan if (rk_mode == RK_MODE_CTS && len <= AES_BLOCK_SIZE) { 83849a2135eSLin Jinhan printf("CTS mode length %u < 16Byte\n", (u32)len); 83949a2135eSLin Jinhan return -EINVAL; 84049a2135eSLin Jinhan } 84149a2135eSLin Jinhan 84249a2135eSLin Jinhan tmp_len = (rk_mode == RK_MODE_CTR) ? ROUNDUP(len, AES_BLOCK_SIZE) : len; 84349a2135eSLin Jinhan 84449a2135eSLin Jinhan data_desc = align_malloc(sizeof(*data_desc), LLI_ADDR_ALIGN_SIZE); 84549a2135eSLin Jinhan if (!data_desc) 84649a2135eSLin Jinhan goto exit; 84749a2135eSLin Jinhan 84849a2135eSLin Jinhan if (IS_ALIGNED((ulong)in, DATA_ADDR_ALIGN_SIZE) && tmp_len == len) 84949a2135eSLin Jinhan dma_in = (void *)in; 85049a2135eSLin Jinhan else 85149a2135eSLin Jinhan dma_in = align_malloc(tmp_len, DATA_ADDR_ALIGN_SIZE); 85249a2135eSLin Jinhan if (!dma_in) 85349a2135eSLin Jinhan goto exit; 85449a2135eSLin Jinhan 85549a2135eSLin Jinhan if (out) { 85649a2135eSLin Jinhan if (IS_ALIGNED((ulong)out, DATA_ADDR_ALIGN_SIZE) && 85749a2135eSLin Jinhan tmp_len == len) 85849a2135eSLin Jinhan dma_out = out; 85949a2135eSLin Jinhan else 86049a2135eSLin Jinhan dma_out = align_malloc(tmp_len, DATA_ADDR_ALIGN_SIZE); 86149a2135eSLin Jinhan if (!dma_out) 86249a2135eSLin Jinhan goto exit; 86349a2135eSLin Jinhan dst_len = tmp_len; 86449a2135eSLin Jinhan } 86549a2135eSLin Jinhan 86649a2135eSLin Jinhan memset(data_desc, 0x00, sizeof(*data_desc)); 86749a2135eSLin Jinhan if (dma_in != in) 86849a2135eSLin Jinhan memcpy(dma_in, in, len); 86949a2135eSLin Jinhan 87049a2135eSLin Jinhan data_desc->src_addr = (u32)virt_to_phys(dma_in); 87149a2135eSLin Jinhan data_desc->src_len = tmp_len; 87249a2135eSLin Jinhan data_desc->dst_addr = (u32)virt_to_phys(dma_out); 87349a2135eSLin Jinhan data_desc->dst_len = dst_len; 874d9332f1cSLin Jinhan data_desc->dma_ctrl = LLI_DMA_CTRL_LAST; 875d9332f1cSLin Jinhan 876d9332f1cSLin Jinhan if (IS_MAC_MODE(rk_mode)) { 877d9332f1cSLin Jinhan expt_int = CRYPTO_LIST_DONE_INT_ST; 878d9332f1cSLin Jinhan data_desc->dma_ctrl |= LLI_DMA_CTRL_LIST_DONE; 879d9332f1cSLin Jinhan } else { 88049a2135eSLin Jinhan expt_int = CRYPTO_DST_ITEM_DONE_INT_ST; 881d9332f1cSLin Jinhan data_desc->dma_ctrl |= LLI_DMA_CTRL_DST_DONE; 882d9332f1cSLin Jinhan } 88349a2135eSLin Jinhan 884c3ce9937SLin Jinhan if (rk_mode == RK_MODE_CCM || rk_mode == RK_MODE_GCM) { 885c3ce9937SLin Jinhan u32 aad_tmp_len = 0; 886c3ce9937SLin Jinhan 887c3ce9937SLin Jinhan data_desc->user_define = LLI_USER_STRING_START | 888c3ce9937SLin Jinhan LLI_USER_STRING_LAST | 889c3ce9937SLin Jinhan (key_chn << 4); 890c3ce9937SLin Jinhan 891c3ce9937SLin Jinhan aad_desc = align_malloc(sizeof(*aad_desc), LLI_ADDR_ALIGN_SIZE); 892c3ce9937SLin Jinhan if (!aad_desc) 893c3ce9937SLin Jinhan goto exit; 894c3ce9937SLin Jinhan 895c3ce9937SLin Jinhan memset(aad_desc, 0x00, sizeof(*aad_desc)); 896c3ce9937SLin Jinhan aad_desc->next_addr = (u32)virt_to_phys(data_desc); 897c3ce9937SLin Jinhan aad_desc->user_define = LLI_USER_CPIHER_START | 898c3ce9937SLin Jinhan LLI_USER_STRING_START | 899c3ce9937SLin Jinhan LLI_USER_STRING_LAST | 900c3ce9937SLin Jinhan LLI_USER_STRING_AAD | 901c3ce9937SLin Jinhan (key_chn << 4); 902c3ce9937SLin Jinhan 903c3ce9937SLin Jinhan if (rk_mode == RK_MODE_CCM) { 904c3ce9937SLin Jinhan u8 padding[AES_BLOCK_SIZE]; 905c3ce9937SLin Jinhan u32 padding_size = 0; 906c3ce9937SLin Jinhan 907c3ce9937SLin Jinhan memset(padding, 0x00, sizeof(padding)); 908c3ce9937SLin Jinhan ccm_aad_padding(aad_len, padding, &padding_size); 909c3ce9937SLin Jinhan 910c3ce9937SLin Jinhan aad_tmp_len = aad_len + AES_BLOCK_SIZE + padding_size; 911c3ce9937SLin Jinhan aad_tmp_len = ROUNDUP(aad_tmp_len, AES_BLOCK_SIZE); 912c3ce9937SLin Jinhan aad_tmp = align_malloc(aad_tmp_len, 913c3ce9937SLin Jinhan DATA_ADDR_ALIGN_SIZE); 914c3ce9937SLin Jinhan if (!aad_tmp) 915c3ce9937SLin Jinhan goto exit; 916c3ce9937SLin Jinhan 917c3ce9937SLin Jinhan /* read iv data from reg */ 918c3ce9937SLin Jinhan get_iv_reg(key_chn, aad_tmp, AES_BLOCK_SIZE); 919c3ce9937SLin Jinhan ccm_compose_aad_iv(aad_tmp, tmp_len, tag_len); 920c3ce9937SLin Jinhan memcpy(aad_tmp + AES_BLOCK_SIZE, padding, padding_size); 921c3ce9937SLin Jinhan memset(aad_tmp + aad_tmp_len - AES_BLOCK_SIZE, 922c3ce9937SLin Jinhan 0x00, AES_BLOCK_SIZE); 923c3ce9937SLin Jinhan memcpy(aad_tmp + AES_BLOCK_SIZE + padding_size, 924c3ce9937SLin Jinhan aad, aad_len); 925c3ce9937SLin Jinhan } else { 926c3ce9937SLin Jinhan aad_tmp_len = aad_len; 927b83c40a4SLin Jinhan if (IS_ALIGNED((ulong)aad, DATA_ADDR_ALIGN_SIZE)) { 928b83c40a4SLin Jinhan aad_tmp = (void *)aad; 929b83c40a4SLin Jinhan } else { 930c3ce9937SLin Jinhan aad_tmp = align_malloc(aad_tmp_len, 931c3ce9937SLin Jinhan DATA_ADDR_ALIGN_SIZE); 932c3ce9937SLin Jinhan if (!aad_tmp) 933c3ce9937SLin Jinhan goto exit; 934c3ce9937SLin Jinhan 935c3ce9937SLin Jinhan memcpy(aad_tmp, aad, aad_tmp_len); 936b83c40a4SLin Jinhan } 937b83c40a4SLin Jinhan 938c3ce9937SLin Jinhan set_aad_len_reg(key_chn, aad_tmp_len); 939c3ce9937SLin Jinhan set_pc_len_reg(key_chn, tmp_len); 940c3ce9937SLin Jinhan } 941c3ce9937SLin Jinhan 942c3ce9937SLin Jinhan aad_desc->src_addr = (u32)virt_to_phys(aad_tmp); 943c3ce9937SLin Jinhan aad_desc->src_len = aad_tmp_len; 944c3ce9937SLin Jinhan crypto_write((u32)virt_to_phys(aad_desc), CRYPTO_DMA_LLI_ADDR); 945c3ce9937SLin Jinhan cache_op_inner(DCACHE_AREA_CLEAN, aad_tmp, aad_tmp_len); 946c3ce9937SLin Jinhan cache_op_inner(DCACHE_AREA_CLEAN, aad_desc, sizeof(*aad_desc)); 947c3ce9937SLin Jinhan } else { 948c3ce9937SLin Jinhan data_desc->user_define = LLI_USER_CPIHER_START | 949c3ce9937SLin Jinhan LLI_USER_STRING_START | 950c3ce9937SLin Jinhan LLI_USER_STRING_LAST | 951c3ce9937SLin Jinhan (key_chn << 4); 95249a2135eSLin Jinhan crypto_write((u32)virt_to_phys(data_desc), CRYPTO_DMA_LLI_ADDR); 953c3ce9937SLin Jinhan } 95449a2135eSLin Jinhan 95549a2135eSLin Jinhan cache_op_inner(DCACHE_AREA_CLEAN, data_desc, sizeof(*data_desc)); 95649a2135eSLin Jinhan cache_op_inner(DCACHE_AREA_CLEAN, dma_in, tmp_len); 95749a2135eSLin Jinhan cache_op_inner(DCACHE_AREA_INVALIDATE, dma_out, tmp_len); 95849a2135eSLin Jinhan 95949a2135eSLin Jinhan /* din_swap set 1, dout_swap set 1, default 1. */ 96049a2135eSLin Jinhan crypto_write(0x00030003, CRYPTO_FIFO_CTL); 96149a2135eSLin Jinhan crypto_write(CRYPTO_DST_ITEM_DONE_INT_EN | CRYPTO_LIST_DONE_INT_EN, 96249a2135eSLin Jinhan CRYPTO_DMA_INT_EN); 96349a2135eSLin Jinhan 96449a2135eSLin Jinhan reg_ctrl = crypto_read(CRYPTO_BC_CTL) | CRYPTO_BC_ENABLE; 96549a2135eSLin Jinhan crypto_write(reg_ctrl | CRYPTO_WRITE_MASK_ALL, CRYPTO_BC_CTL); 96649a2135eSLin Jinhan crypto_write(0x00010001, CRYPTO_DMA_CTL);//start 96749a2135eSLin Jinhan 96849a2135eSLin Jinhan mask = ~(mask | CRYPTO_SYNC_LOCKSTEP_INT_ST); 96949a2135eSLin Jinhan 97049a2135eSLin Jinhan /* wait calc ok */ 97149a2135eSLin Jinhan ret = RK_POLL_TIMEOUT(!(crypto_read(CRYPTO_DMA_INT_ST) & mask), 97249a2135eSLin Jinhan RK_CRYPTO_TIMEOUT); 97349a2135eSLin Jinhan tmp = crypto_read(CRYPTO_DMA_INT_ST); 97449a2135eSLin Jinhan crypto_write(tmp, CRYPTO_DMA_INT_ST); 97549a2135eSLin Jinhan 97649a2135eSLin Jinhan if ((tmp & mask) == expt_int) { 97749a2135eSLin Jinhan if (out && out != dma_out) 97849a2135eSLin Jinhan memcpy(out, dma_out, len); 979d9332f1cSLin Jinhan 980d9332f1cSLin Jinhan if (IS_NEED_TAG(rk_mode)) { 981d9332f1cSLin Jinhan ret = WAIT_TAG_VALID(key_chn, RK_CRYPTO_TIMEOUT); 982d9332f1cSLin Jinhan get_tag_from_reg(key_chn, tag, AES_BLOCK_SIZE); 983d9332f1cSLin Jinhan } 98449a2135eSLin Jinhan } else { 9856b53126aSLin Jinhan dump_crypto_state(data_desc, tmp, expt_int, in, out, len, ret); 98649a2135eSLin Jinhan ret = -1; 98749a2135eSLin Jinhan } 98849a2135eSLin Jinhan 98949a2135eSLin Jinhan exit: 99049a2135eSLin Jinhan crypto_write(0xffff0000, CRYPTO_BC_CTL);//bc_ctl disable 99149a2135eSLin Jinhan align_free(data_desc); 992c3ce9937SLin Jinhan align_free(aad_desc); 993b83c40a4SLin Jinhan if (dma_in != in) 99449a2135eSLin Jinhan align_free(dma_in); 995b83c40a4SLin Jinhan if (out && dma_out != out) 99649a2135eSLin Jinhan align_free(dma_out); 997b83c40a4SLin Jinhan if (aad && aad != aad_tmp) 998b83c40a4SLin Jinhan align_free(aad_tmp); 99949a2135eSLin Jinhan 100049a2135eSLin Jinhan return ret; 100149a2135eSLin Jinhan } 100249a2135eSLin Jinhan 100349a2135eSLin Jinhan static int hw_aes_init(u32 chn, const u8 *key, const u8 *twk_key, u32 key_len, 100449a2135eSLin Jinhan const u8 *iv, u32 iv_len, u32 mode, bool enc) 100549a2135eSLin Jinhan { 100649a2135eSLin Jinhan u32 rk_mode = RK_GET_RK_MODE(mode); 100749a2135eSLin Jinhan 1008d9332f1cSLin Jinhan if (rk_mode > RK_MODE_XTS) 1009d9332f1cSLin Jinhan return -EINVAL; 1010d9332f1cSLin Jinhan 101149a2135eSLin Jinhan if (iv_len > AES_BLOCK_SIZE) 101249a2135eSLin Jinhan return -EINVAL; 101349a2135eSLin Jinhan 1014d9332f1cSLin Jinhan if (IS_NEED_IV(rk_mode)) { 101549a2135eSLin Jinhan if (!iv || iv_len != AES_BLOCK_SIZE) 101649a2135eSLin Jinhan return -EINVAL; 101749a2135eSLin Jinhan } else { 101849a2135eSLin Jinhan iv_len = 0; 101949a2135eSLin Jinhan } 102049a2135eSLin Jinhan 102149a2135eSLin Jinhan if (rk_mode == RK_MODE_XTS) { 102249a2135eSLin Jinhan if (key_len != AES_KEYSIZE_128 && key_len != AES_KEYSIZE_256) 102349a2135eSLin Jinhan return -EINVAL; 102449a2135eSLin Jinhan 102549a2135eSLin Jinhan if (!key || !twk_key) 102649a2135eSLin Jinhan return -EINVAL; 102749a2135eSLin Jinhan } else { 102849a2135eSLin Jinhan if (key_len != AES_KEYSIZE_128 && 102949a2135eSLin Jinhan key_len != AES_KEYSIZE_192 && 103049a2135eSLin Jinhan key_len != AES_KEYSIZE_256) 103149a2135eSLin Jinhan return -EINVAL; 103249a2135eSLin Jinhan } 103349a2135eSLin Jinhan 103449a2135eSLin Jinhan return hw_cipher_init(chn, key, twk_key, key_len, iv, iv_len, 103549a2135eSLin Jinhan CRYPTO_AES, mode, enc); 103649a2135eSLin Jinhan } 103749a2135eSLin Jinhan 103849a2135eSLin Jinhan static int hw_sm4_init(u32 chn, const u8 *key, const u8 *twk_key, u32 key_len, 103949a2135eSLin Jinhan const u8 *iv, u32 iv_len, u32 mode, bool enc) 104049a2135eSLin Jinhan { 104149a2135eSLin Jinhan u32 rk_mode = RK_GET_RK_MODE(mode); 104249a2135eSLin Jinhan 1043d9332f1cSLin Jinhan if (rk_mode > RK_MODE_XTS) 1044d9332f1cSLin Jinhan return -EINVAL; 1045d9332f1cSLin Jinhan 104649a2135eSLin Jinhan if (iv_len > SM4_BLOCK_SIZE || key_len != SM4_KEYSIZE) 104749a2135eSLin Jinhan return -EINVAL; 104849a2135eSLin Jinhan 1049d9332f1cSLin Jinhan if (IS_NEED_IV(rk_mode)) { 105049a2135eSLin Jinhan if (!iv || iv_len != SM4_BLOCK_SIZE) 105149a2135eSLin Jinhan return -EINVAL; 105249a2135eSLin Jinhan } else { 105349a2135eSLin Jinhan iv_len = 0; 105449a2135eSLin Jinhan } 105549a2135eSLin Jinhan 105649a2135eSLin Jinhan if (rk_mode == RK_MODE_XTS) { 105749a2135eSLin Jinhan if (!key || !twk_key) 105849a2135eSLin Jinhan return -EINVAL; 105949a2135eSLin Jinhan } 106049a2135eSLin Jinhan 106149a2135eSLin Jinhan return hw_cipher_init(chn, key, twk_key, key_len, iv, iv_len, 106249a2135eSLin Jinhan CRYPTO_SM4, mode, enc); 106349a2135eSLin Jinhan } 106449a2135eSLin Jinhan 106549a2135eSLin Jinhan int rk_crypto_des(struct udevice *dev, u32 mode, const u8 *key, u32 key_len, 106649a2135eSLin Jinhan const u8 *iv, const u8 *in, u8 *out, u32 len, bool enc) 106749a2135eSLin Jinhan { 106849a2135eSLin Jinhan u32 rk_mode = RK_GET_RK_MODE(mode); 106949a2135eSLin Jinhan u8 tmp_key[24]; 107049a2135eSLin Jinhan int ret; 107149a2135eSLin Jinhan 107249a2135eSLin Jinhan if (!is_des_mode(rk_mode)) 107349a2135eSLin Jinhan return -EINVAL; 107449a2135eSLin Jinhan 107549a2135eSLin Jinhan if (key_len == DES_BLOCK_SIZE || key_len == 3 * DES_BLOCK_SIZE) { 107649a2135eSLin Jinhan memcpy(tmp_key, key, key_len); 107749a2135eSLin Jinhan } else if (key_len == 2 * DES_BLOCK_SIZE) { 107849a2135eSLin Jinhan memcpy(tmp_key, key, 16); 107949a2135eSLin Jinhan memcpy(tmp_key + 16, key, 8); 108049a2135eSLin Jinhan key_len = 3 * DES_BLOCK_SIZE; 108149a2135eSLin Jinhan } else { 108249a2135eSLin Jinhan return -EINVAL; 108349a2135eSLin Jinhan } 108449a2135eSLin Jinhan 108549a2135eSLin Jinhan ret = hw_cipher_init(0, tmp_key, NULL, key_len, iv, DES_BLOCK_SIZE, 108649a2135eSLin Jinhan CRYPTO_DES, mode, enc); 108749a2135eSLin Jinhan if (ret) 108849a2135eSLin Jinhan goto exit; 108949a2135eSLin Jinhan 109049a2135eSLin Jinhan ret = hw_cipher_crypt(in, out, len, NULL, 0, 109149a2135eSLin Jinhan NULL, 0, mode); 109249a2135eSLin Jinhan 109349a2135eSLin Jinhan exit: 109449a2135eSLin Jinhan return ret; 109549a2135eSLin Jinhan } 109649a2135eSLin Jinhan 109749a2135eSLin Jinhan int rk_crypto_aes(struct udevice *dev, u32 mode, 109849a2135eSLin Jinhan const u8 *key, const u8 *twk_key, u32 key_len, 109949a2135eSLin Jinhan const u8 *iv, u32 iv_len, 110049a2135eSLin Jinhan const u8 *in, u8 *out, u32 len, bool enc) 110149a2135eSLin Jinhan { 110249a2135eSLin Jinhan int ret; 110349a2135eSLin Jinhan 110449a2135eSLin Jinhan /* RV1126/RV1109 do not support aes-192 */ 110549a2135eSLin Jinhan #if defined(CONFIG_ROCKCHIP_RV1126) 110649a2135eSLin Jinhan if (key_len == AES_KEYSIZE_192) 110749a2135eSLin Jinhan return -EINVAL; 110849a2135eSLin Jinhan #endif 110949a2135eSLin Jinhan 111049a2135eSLin Jinhan ret = hw_aes_init(0, key, twk_key, key_len, iv, iv_len, mode, enc); 111149a2135eSLin Jinhan if (ret) 111249a2135eSLin Jinhan return ret; 111349a2135eSLin Jinhan 111449a2135eSLin Jinhan return hw_cipher_crypt(in, out, len, NULL, 0, 111549a2135eSLin Jinhan NULL, 0, mode); 111649a2135eSLin Jinhan } 111749a2135eSLin Jinhan 111849a2135eSLin Jinhan int rk_crypto_sm4(struct udevice *dev, u32 mode, 111949a2135eSLin Jinhan const u8 *key, const u8 *twk_key, u32 key_len, 112049a2135eSLin Jinhan const u8 *iv, u32 iv_len, 112149a2135eSLin Jinhan const u8 *in, u8 *out, u32 len, bool enc) 112249a2135eSLin Jinhan { 112349a2135eSLin Jinhan int ret; 112449a2135eSLin Jinhan 112549a2135eSLin Jinhan ret = hw_sm4_init(0, key, twk_key, key_len, iv, iv_len, mode, enc); 112649a2135eSLin Jinhan if (ret) 112749a2135eSLin Jinhan return ret; 112849a2135eSLin Jinhan 112949a2135eSLin Jinhan return hw_cipher_crypt(in, out, len, NULL, 0, NULL, 0, mode); 113049a2135eSLin Jinhan } 113149a2135eSLin Jinhan 113249a2135eSLin Jinhan int rockchip_crypto_cipher(struct udevice *dev, cipher_context *ctx, 113349a2135eSLin Jinhan const u8 *in, u8 *out, u32 len, bool enc) 113449a2135eSLin Jinhan { 113549a2135eSLin Jinhan switch (ctx->algo) { 113649a2135eSLin Jinhan case CRYPTO_DES: 113749a2135eSLin Jinhan return rk_crypto_des(dev, ctx->mode, ctx->key, ctx->key_len, 113849a2135eSLin Jinhan ctx->iv, in, out, len, enc); 113949a2135eSLin Jinhan case CRYPTO_AES: 114049a2135eSLin Jinhan return rk_crypto_aes(dev, ctx->mode, 114149a2135eSLin Jinhan ctx->key, ctx->twk_key, ctx->key_len, 114249a2135eSLin Jinhan ctx->iv, ctx->iv_len, in, out, len, enc); 114349a2135eSLin Jinhan case CRYPTO_SM4: 114449a2135eSLin Jinhan return rk_crypto_sm4(dev, ctx->mode, 114549a2135eSLin Jinhan ctx->key, ctx->twk_key, ctx->key_len, 114649a2135eSLin Jinhan ctx->iv, ctx->iv_len, in, out, len, enc); 114749a2135eSLin Jinhan default: 114849a2135eSLin Jinhan return -EINVAL; 114949a2135eSLin Jinhan } 115049a2135eSLin Jinhan } 1151d9332f1cSLin Jinhan 1152d9332f1cSLin Jinhan int rk_crypto_mac(struct udevice *dev, u32 algo, u32 mode, 1153d9332f1cSLin Jinhan const u8 *key, u32 key_len, 1154d9332f1cSLin Jinhan const u8 *in, u32 len, u8 *tag) 1155d9332f1cSLin Jinhan { 1156d9332f1cSLin Jinhan u32 rk_mode = RK_GET_RK_MODE(mode); 1157d9332f1cSLin Jinhan int ret; 1158d9332f1cSLin Jinhan 1159d9332f1cSLin Jinhan if (!IS_MAC_MODE(rk_mode)) 1160d9332f1cSLin Jinhan return -EINVAL; 1161d9332f1cSLin Jinhan 1162d9332f1cSLin Jinhan if (algo != CRYPTO_AES && algo != CRYPTO_SM4) 1163d9332f1cSLin Jinhan return -EINVAL; 1164d9332f1cSLin Jinhan 1165d9332f1cSLin Jinhan /* RV1126/RV1109 do not support aes-192 */ 1166d9332f1cSLin Jinhan #if defined(CONFIG_ROCKCHIP_RV1126) 1167d9332f1cSLin Jinhan if (algo == CRYPTO_AES && key_len == AES_KEYSIZE_192) 1168d9332f1cSLin Jinhan return -EINVAL; 1169d9332f1cSLin Jinhan #endif 1170d9332f1cSLin Jinhan 1171d9332f1cSLin Jinhan ret = hw_cipher_init(g_key_chn, key, NULL, key_len, NULL, 0, 1172d9332f1cSLin Jinhan algo, mode, true); 1173d9332f1cSLin Jinhan if (ret) 1174d9332f1cSLin Jinhan return ret; 1175d9332f1cSLin Jinhan 1176d9332f1cSLin Jinhan return hw_cipher_crypt(in, NULL, len, NULL, 0, 1177d9332f1cSLin Jinhan tag, AES_BLOCK_SIZE, mode); 1178d9332f1cSLin Jinhan } 1179d9332f1cSLin Jinhan 1180d9332f1cSLin Jinhan int rockchip_crypto_mac(struct udevice *dev, cipher_context *ctx, 1181d9332f1cSLin Jinhan const u8 *in, u32 len, u8 *tag) 1182d9332f1cSLin Jinhan { 1183d9332f1cSLin Jinhan return rk_crypto_mac(dev, ctx->algo, ctx->mode, 1184d9332f1cSLin Jinhan ctx->key, ctx->key_len, in, len, tag); 1185d9332f1cSLin Jinhan } 1186d9332f1cSLin Jinhan 1187c3ce9937SLin Jinhan int rk_crypto_ae(struct udevice *dev, u32 algo, u32 mode, 1188c3ce9937SLin Jinhan const u8 *key, u32 key_len, const u8 *nonce, u32 nonce_len, 1189c3ce9937SLin Jinhan const u8 *in, u32 len, const u8 *aad, u32 aad_len, 1190c3ce9937SLin Jinhan u8 *out, u8 *tag) 1191c3ce9937SLin Jinhan { 1192c3ce9937SLin Jinhan u32 rk_mode = RK_GET_RK_MODE(mode); 1193c3ce9937SLin Jinhan int ret; 1194c3ce9937SLin Jinhan 1195c3ce9937SLin Jinhan if (!IS_AE_MODE(rk_mode)) 1196c3ce9937SLin Jinhan return -EINVAL; 1197c3ce9937SLin Jinhan 1198c3ce9937SLin Jinhan if (algo != CRYPTO_AES && algo != CRYPTO_SM4) 1199c3ce9937SLin Jinhan return -EINVAL; 1200c3ce9937SLin Jinhan 1201c3ce9937SLin Jinhan /* RV1126/RV1109 do not support aes-192 */ 1202c3ce9937SLin Jinhan #if defined(CONFIG_ROCKCHIP_RV1126) 1203c3ce9937SLin Jinhan if (algo == CRYPTO_AES && key_len == AES_KEYSIZE_192) 1204c3ce9937SLin Jinhan return -EINVAL; 1205c3ce9937SLin Jinhan #endif 1206c3ce9937SLin Jinhan 1207c3ce9937SLin Jinhan ret = hw_cipher_init(g_key_chn, key, NULL, key_len, nonce, nonce_len, 1208c3ce9937SLin Jinhan algo, mode, true); 1209c3ce9937SLin Jinhan if (ret) 1210c3ce9937SLin Jinhan return ret; 1211c3ce9937SLin Jinhan 1212c3ce9937SLin Jinhan return hw_cipher_crypt(in, out, len, aad, aad_len, 1213c3ce9937SLin Jinhan tag, AES_BLOCK_SIZE, mode); 1214c3ce9937SLin Jinhan } 1215c3ce9937SLin Jinhan 1216c3ce9937SLin Jinhan int rockchip_crypto_ae(struct udevice *dev, cipher_context *ctx, 1217c3ce9937SLin Jinhan const u8 *in, u32 len, const u8 *aad, u32 aad_len, 1218c3ce9937SLin Jinhan u8 *out, u8 *tag) 1219c3ce9937SLin Jinhan 1220c3ce9937SLin Jinhan { 1221c3ce9937SLin Jinhan return rk_crypto_ae(dev, ctx->algo, ctx->mode, ctx->key, ctx->key_len, 1222c3ce9937SLin Jinhan ctx->iv, ctx->iv_len, in, len, 1223c3ce9937SLin Jinhan aad, aad_len, out, tag); 1224c3ce9937SLin Jinhan } 1225c3ce9937SLin Jinhan 122649a2135eSLin Jinhan #endif 122749a2135eSLin Jinhan 1228864e581cSLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_RSA) 1229b353a43cSLin Jinhan static int rockchip_crypto_rsa_verify(struct udevice *dev, rsa_key *ctx, 1230b353a43cSLin Jinhan u8 *sign, u8 *output) 1231b353a43cSLin Jinhan { 1232b353a43cSLin Jinhan struct mpa_num *mpa_m = NULL, *mpa_e = NULL, *mpa_n = NULL; 1233b353a43cSLin Jinhan struct mpa_num *mpa_c = NULL, *mpa_result = NULL; 1234b353a43cSLin Jinhan u32 n_bits, n_words; 1235b353a43cSLin Jinhan u32 *rsa_result; 1236b353a43cSLin Jinhan int ret; 1237b353a43cSLin Jinhan 1238b353a43cSLin Jinhan if (!ctx) 1239b353a43cSLin Jinhan return -EINVAL; 1240b353a43cSLin Jinhan 1241b353a43cSLin Jinhan if (ctx->algo != CRYPTO_RSA512 && 1242b353a43cSLin Jinhan ctx->algo != CRYPTO_RSA1024 && 1243b353a43cSLin Jinhan ctx->algo != CRYPTO_RSA2048 && 1244b353a43cSLin Jinhan ctx->algo != CRYPTO_RSA3072 && 1245b353a43cSLin Jinhan ctx->algo != CRYPTO_RSA4096) 1246b353a43cSLin Jinhan return -EINVAL; 1247b353a43cSLin Jinhan 1248b353a43cSLin Jinhan n_bits = crypto_algo_nbits(ctx->algo); 1249b353a43cSLin Jinhan n_words = BITS2WORD(n_bits); 1250b353a43cSLin Jinhan 1251b353a43cSLin Jinhan rsa_result = malloc(BITS2BYTE(n_bits)); 1252b353a43cSLin Jinhan if (!rsa_result) 1253b353a43cSLin Jinhan return -ENOMEM; 1254b353a43cSLin Jinhan 1255b353a43cSLin Jinhan memset(rsa_result, 0x00, BITS2BYTE(n_bits)); 1256b353a43cSLin Jinhan 1257b353a43cSLin Jinhan ret = rk_mpa_alloc(&mpa_m); 1258b353a43cSLin Jinhan ret |= rk_mpa_alloc(&mpa_e); 1259b353a43cSLin Jinhan ret |= rk_mpa_alloc(&mpa_n); 1260b353a43cSLin Jinhan ret |= rk_mpa_alloc(&mpa_c); 1261b353a43cSLin Jinhan ret |= rk_mpa_alloc(&mpa_result); 1262b353a43cSLin Jinhan if (ret) 1263b353a43cSLin Jinhan goto exit; 1264b353a43cSLin Jinhan 1265b353a43cSLin Jinhan mpa_m->d = (void *)sign; 1266b353a43cSLin Jinhan mpa_e->d = (void *)ctx->e; 1267b353a43cSLin Jinhan mpa_n->d = (void *)ctx->n; 1268b353a43cSLin Jinhan mpa_c->d = (void *)ctx->c; 1269b353a43cSLin Jinhan mpa_result->d = (void *)rsa_result; 1270b353a43cSLin Jinhan 1271b353a43cSLin Jinhan mpa_m->size = n_words; 1272b353a43cSLin Jinhan mpa_e->size = n_words; 1273b353a43cSLin Jinhan mpa_n->size = n_words; 1274b353a43cSLin Jinhan mpa_c->size = n_words; 1275b353a43cSLin Jinhan mpa_result->size = n_words; 1276b353a43cSLin Jinhan 1277b353a43cSLin Jinhan ret = rk_exptmod_np(mpa_m, mpa_e, mpa_n, mpa_c, mpa_result); 1278b353a43cSLin Jinhan if (!ret) 1279b353a43cSLin Jinhan memcpy(output, rsa_result, BITS2BYTE(n_bits)); 1280b353a43cSLin Jinhan 1281b353a43cSLin Jinhan exit: 1282b353a43cSLin Jinhan free(rsa_result); 1283b353a43cSLin Jinhan rk_mpa_free(&mpa_m); 1284b353a43cSLin Jinhan rk_mpa_free(&mpa_e); 1285b353a43cSLin Jinhan rk_mpa_free(&mpa_n); 1286b353a43cSLin Jinhan rk_mpa_free(&mpa_c); 1287b353a43cSLin Jinhan rk_mpa_free(&mpa_result); 1288b353a43cSLin Jinhan 1289b353a43cSLin Jinhan return ret; 1290b353a43cSLin Jinhan } 1291864e581cSLin Jinhan #endif 1292b353a43cSLin Jinhan 1293b353a43cSLin Jinhan static const struct dm_crypto_ops rockchip_crypto_ops = { 1294b353a43cSLin Jinhan .capability = rockchip_crypto_capability, 1295b353a43cSLin Jinhan .sha_init = rockchip_crypto_sha_init, 1296b353a43cSLin Jinhan .sha_update = rockchip_crypto_sha_update, 1297b353a43cSLin Jinhan .sha_final = rockchip_crypto_sha_final, 129849a2135eSLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_RSA) 1299b353a43cSLin Jinhan .rsa_verify = rockchip_crypto_rsa_verify, 130049a2135eSLin Jinhan #endif 130149a2135eSLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_HMAC) 130249a2135eSLin Jinhan .hmac_init = rockchip_crypto_hmac_init, 130349a2135eSLin Jinhan .hmac_update = rockchip_crypto_hmac_update, 130449a2135eSLin Jinhan .hmac_final = rockchip_crypto_hmac_final, 130549a2135eSLin Jinhan #endif 130649a2135eSLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_CIPHER) 130749a2135eSLin Jinhan .cipher_crypt = rockchip_crypto_cipher, 1308d9332f1cSLin Jinhan .cipher_mac = rockchip_crypto_mac, 1309c3ce9937SLin Jinhan .cipher_ae = rockchip_crypto_ae, 131049a2135eSLin Jinhan #endif 1311b353a43cSLin Jinhan }; 1312b353a43cSLin Jinhan 1313b353a43cSLin Jinhan /* 1314b353a43cSLin Jinhan * Only use "clocks" to parse crypto clock id and use rockchip_get_clk(). 1315b353a43cSLin Jinhan * Because we always add crypto node in U-Boot dts, when kernel dtb enabled : 1316b353a43cSLin Jinhan * 1317b353a43cSLin Jinhan * 1. There is cru phandle mismatch between U-Boot and kernel dtb; 1318b353a43cSLin Jinhan * 2. CONFIG_OF_SPL_REMOVE_PROPS removes clock property; 1319b353a43cSLin Jinhan */ 1320b353a43cSLin Jinhan static int rockchip_crypto_ofdata_to_platdata(struct udevice *dev) 1321b353a43cSLin Jinhan { 1322b353a43cSLin Jinhan struct rockchip_crypto_priv *priv = dev_get_priv(dev); 1323b353a43cSLin Jinhan int len, ret = -EINVAL; 1324b353a43cSLin Jinhan 1325*a24b2aebSLin Jinhan memset(priv, 0x00, sizeof(*priv)); 1326*a24b2aebSLin Jinhan 1327*a24b2aebSLin Jinhan priv->reg = (fdt_addr_t)dev_read_addr_ptr(dev); 1328*a24b2aebSLin Jinhan if (priv->reg == FDT_ADDR_T_NONE) 1329*a24b2aebSLin Jinhan return -EINVAL; 1330*a24b2aebSLin Jinhan 1331*a24b2aebSLin Jinhan crypto_base = priv->reg; 1332*a24b2aebSLin Jinhan 1333*a24b2aebSLin Jinhan /* if there is no clocks in dts, just skip it */ 1334b353a43cSLin Jinhan if (!dev_read_prop(dev, "clocks", &len)) { 1335b353a43cSLin Jinhan printf("Can't find \"clocks\" property\n"); 1336*a24b2aebSLin Jinhan return 0; 1337b353a43cSLin Jinhan } 1338b353a43cSLin Jinhan 1339b353a43cSLin Jinhan memset(priv, 0x00, sizeof(*priv)); 1340b353a43cSLin Jinhan priv->clocks = malloc(len); 1341b353a43cSLin Jinhan if (!priv->clocks) 1342b353a43cSLin Jinhan return -ENOMEM; 1343b353a43cSLin Jinhan 1344b353a43cSLin Jinhan priv->nclocks = len / sizeof(u32); 1345b353a43cSLin Jinhan if (dev_read_u32_array(dev, "clocks", (u32 *)priv->clocks, 1346b353a43cSLin Jinhan priv->nclocks)) { 1347b353a43cSLin Jinhan printf("Can't read \"clocks\" property\n"); 1348b353a43cSLin Jinhan ret = -EINVAL; 1349b353a43cSLin Jinhan goto exit; 1350b353a43cSLin Jinhan } 1351b353a43cSLin Jinhan 1352b353a43cSLin Jinhan if (!dev_read_prop(dev, "clock-frequency", &len)) { 1353b353a43cSLin Jinhan printf("Can't find \"clock-frequency\" property\n"); 1354b353a43cSLin Jinhan ret = -EINVAL; 1355b353a43cSLin Jinhan goto exit; 1356b353a43cSLin Jinhan } 1357b353a43cSLin Jinhan 1358b353a43cSLin Jinhan priv->frequencies = malloc(len); 1359b353a43cSLin Jinhan if (!priv->frequencies) { 1360b353a43cSLin Jinhan ret = -ENOMEM; 1361b353a43cSLin Jinhan goto exit; 1362b353a43cSLin Jinhan } 1363b353a43cSLin Jinhan 1364b353a43cSLin Jinhan priv->nclocks = len / sizeof(u32); 1365b353a43cSLin Jinhan if (dev_read_u32_array(dev, "clock-frequency", priv->frequencies, 1366b353a43cSLin Jinhan priv->nclocks)) { 1367b353a43cSLin Jinhan printf("Can't read \"clock-frequency\" property\n"); 1368b353a43cSLin Jinhan ret = -EINVAL; 1369b353a43cSLin Jinhan goto exit; 1370b353a43cSLin Jinhan } 1371b353a43cSLin Jinhan 1372b353a43cSLin Jinhan return 0; 1373b353a43cSLin Jinhan exit: 1374b353a43cSLin Jinhan if (priv->clocks) 1375b353a43cSLin Jinhan free(priv->clocks); 1376b353a43cSLin Jinhan 1377b353a43cSLin Jinhan if (priv->frequencies) 1378b353a43cSLin Jinhan free(priv->frequencies); 1379b353a43cSLin Jinhan 1380b353a43cSLin Jinhan return ret; 1381b353a43cSLin Jinhan } 1382b353a43cSLin Jinhan 1383*a24b2aebSLin Jinhan static int rk_crypto_set_clk(struct rockchip_crypto_priv *priv) 1384b353a43cSLin Jinhan { 1385*a24b2aebSLin Jinhan int i, ret; 1386b353a43cSLin Jinhan u32* clocks; 1387b353a43cSLin Jinhan 1388*a24b2aebSLin Jinhan if (!priv->clocks && priv->nclocks == 0) 1389*a24b2aebSLin Jinhan return 0; 139049a2135eSLin Jinhan 1391*a24b2aebSLin Jinhan #ifdef CONFIG_CLK_SCMI 1392*a24b2aebSLin Jinhan ret = rockchip_get_scmi_clk(&priv->clk.dev); 1393*a24b2aebSLin Jinhan #else 1394b353a43cSLin Jinhan ret = rockchip_get_clk(&priv->clk.dev); 1395*a24b2aebSLin Jinhan #endif 1396*a24b2aebSLin Jinhan if (priv->nclocks && ret) { 1397b353a43cSLin Jinhan printf("Failed to get clk device, ret=%d\n", ret); 1398b353a43cSLin Jinhan return ret; 1399b353a43cSLin Jinhan } 1400b353a43cSLin Jinhan 1401b353a43cSLin Jinhan clocks = (u32 *)priv->clocks; 1402b353a43cSLin Jinhan for (i = 0; i < priv->nclocks; i++) { 1403b353a43cSLin Jinhan priv->clk.id = clocks[i * 2 + 1]; 1404b353a43cSLin Jinhan ret = clk_set_rate(&priv->clk, priv->frequencies[i]); 1405b353a43cSLin Jinhan if (ret < 0) { 1406b353a43cSLin Jinhan printf("%s: Failed to set clk(%ld): ret=%d\n", 1407b353a43cSLin Jinhan __func__, priv->clk.id, ret); 1408b353a43cSLin Jinhan return ret; 1409b353a43cSLin Jinhan } 1410b353a43cSLin Jinhan } 1411b353a43cSLin Jinhan 1412*a24b2aebSLin Jinhan return 0; 1413*a24b2aebSLin Jinhan } 1414*a24b2aebSLin Jinhan 1415*a24b2aebSLin Jinhan static int rockchip_crypto_probe(struct udevice *dev) 1416*a24b2aebSLin Jinhan { 1417*a24b2aebSLin Jinhan struct rockchip_crypto_priv *priv = dev_get_priv(dev); 1418*a24b2aebSLin Jinhan struct rk_crypto_soc_data *sdata; 1419*a24b2aebSLin Jinhan int ret = 0; 1420*a24b2aebSLin Jinhan 1421*a24b2aebSLin Jinhan sdata = (struct rk_crypto_soc_data *)dev_get_driver_data(dev); 1422*a24b2aebSLin Jinhan priv->soc_data = sdata; 1423*a24b2aebSLin Jinhan 1424*a24b2aebSLin Jinhan priv->hw_ctx = memalign(LLI_ADDR_ALIGN_SIZE, 1425*a24b2aebSLin Jinhan sizeof(struct rk_hash_ctx)); 1426*a24b2aebSLin Jinhan if (!priv->hw_ctx) 1427*a24b2aebSLin Jinhan return -ENOMEM; 1428*a24b2aebSLin Jinhan 1429*a24b2aebSLin Jinhan ret = rk_crypto_set_clk(priv); 1430*a24b2aebSLin Jinhan if (ret) 1431*a24b2aebSLin Jinhan return ret; 1432*a24b2aebSLin Jinhan 1433b353a43cSLin Jinhan hw_crypto_reset(); 1434b353a43cSLin Jinhan 1435b353a43cSLin Jinhan return 0; 1436b353a43cSLin Jinhan } 1437b353a43cSLin Jinhan 143849a2135eSLin Jinhan static const struct rk_crypto_soc_data soc_data_base = { 143949a2135eSLin Jinhan .capability = CRYPTO_MD5 | 144049a2135eSLin Jinhan CRYPTO_SHA1 | 144149a2135eSLin Jinhan CRYPTO_SHA256 | 144249a2135eSLin Jinhan CRYPTO_SHA512 | 144349a2135eSLin Jinhan CRYPTO_HMAC_MD5 | 144449a2135eSLin Jinhan CRYPTO_HMAC_SHA1 | 144549a2135eSLin Jinhan CRYPTO_HMAC_SHA256 | 144649a2135eSLin Jinhan CRYPTO_HMAC_SHA512 | 144749a2135eSLin Jinhan CRYPTO_RSA512 | 144849a2135eSLin Jinhan CRYPTO_RSA1024 | 144949a2135eSLin Jinhan CRYPTO_RSA2048 | 145049a2135eSLin Jinhan CRYPTO_RSA3072 | 145149a2135eSLin Jinhan CRYPTO_RSA4096 | 145249a2135eSLin Jinhan CRYPTO_DES | 145349a2135eSLin Jinhan CRYPTO_AES, 145449a2135eSLin Jinhan }; 145549a2135eSLin Jinhan 145649a2135eSLin Jinhan static const struct rk_crypto_soc_data soc_data_base_sm = { 145749a2135eSLin Jinhan .capability = CRYPTO_MD5 | 145849a2135eSLin Jinhan CRYPTO_SHA1 | 145949a2135eSLin Jinhan CRYPTO_SHA256 | 146049a2135eSLin Jinhan CRYPTO_SHA512 | 146149a2135eSLin Jinhan CRYPTO_SM3 | 146249a2135eSLin Jinhan CRYPTO_HMAC_MD5 | 146349a2135eSLin Jinhan CRYPTO_HMAC_SHA1 | 146449a2135eSLin Jinhan CRYPTO_HMAC_SHA256 | 146549a2135eSLin Jinhan CRYPTO_HMAC_SHA512 | 146649a2135eSLin Jinhan CRYPTO_HMAC_SM3 | 146749a2135eSLin Jinhan CRYPTO_RSA512 | 146849a2135eSLin Jinhan CRYPTO_RSA1024 | 146949a2135eSLin Jinhan CRYPTO_RSA2048 | 147049a2135eSLin Jinhan CRYPTO_RSA3072 | 147149a2135eSLin Jinhan CRYPTO_RSA4096 | 147249a2135eSLin Jinhan CRYPTO_DES | 147349a2135eSLin Jinhan CRYPTO_AES | 147449a2135eSLin Jinhan CRYPTO_SM4, 147549a2135eSLin Jinhan }; 147649a2135eSLin Jinhan 147749a2135eSLin Jinhan static const struct rk_crypto_soc_data soc_data_rk1808 = { 147849a2135eSLin Jinhan .capability = CRYPTO_MD5 | 147949a2135eSLin Jinhan CRYPTO_SHA1 | 148049a2135eSLin Jinhan CRYPTO_SHA256 | 148149a2135eSLin Jinhan CRYPTO_HMAC_MD5 | 148249a2135eSLin Jinhan CRYPTO_HMAC_SHA1 | 148349a2135eSLin Jinhan CRYPTO_HMAC_SHA256 | 148449a2135eSLin Jinhan CRYPTO_RSA512 | 148549a2135eSLin Jinhan CRYPTO_RSA1024 | 148649a2135eSLin Jinhan CRYPTO_RSA2048 | 148749a2135eSLin Jinhan CRYPTO_RSA3072 | 148849a2135eSLin Jinhan CRYPTO_RSA4096, 148949a2135eSLin Jinhan }; 149049a2135eSLin Jinhan 1491b353a43cSLin Jinhan static const struct udevice_id rockchip_crypto_ids[] = { 149249a2135eSLin Jinhan { 149349a2135eSLin Jinhan .compatible = "rockchip,px30-crypto", 149449a2135eSLin Jinhan .data = (ulong)&soc_data_base 149549a2135eSLin Jinhan }, 149649a2135eSLin Jinhan { 149749a2135eSLin Jinhan .compatible = "rockchip,rk1808-crypto", 149849a2135eSLin Jinhan .data = (ulong)&soc_data_rk1808 149949a2135eSLin Jinhan }, 150049a2135eSLin Jinhan { 150149a2135eSLin Jinhan .compatible = "rockchip,rk3308-crypto", 150249a2135eSLin Jinhan .data = (ulong)&soc_data_base 150349a2135eSLin Jinhan }, 150449a2135eSLin Jinhan { 150549a2135eSLin Jinhan .compatible = "rockchip,rv1126-crypto", 150649a2135eSLin Jinhan .data = (ulong)&soc_data_base_sm 150749a2135eSLin Jinhan }, 150849a2135eSLin Jinhan { 150949a2135eSLin Jinhan .compatible = "rockchip,rk3568-crypto", 151049a2135eSLin Jinhan .data = (ulong)&soc_data_base_sm 151149a2135eSLin Jinhan }, 15125b3e3895SLin Jinhan { 15135b3e3895SLin Jinhan .compatible = "rockchip,rk3588-crypto", 15145b3e3895SLin Jinhan .data = (ulong)&soc_data_base_sm 15155b3e3895SLin Jinhan }, 1516b353a43cSLin Jinhan { } 1517b353a43cSLin Jinhan }; 1518b353a43cSLin Jinhan 1519b353a43cSLin Jinhan U_BOOT_DRIVER(rockchip_crypto_v2) = { 1520b353a43cSLin Jinhan .name = "rockchip_crypto_v2", 1521b353a43cSLin Jinhan .id = UCLASS_CRYPTO, 1522b353a43cSLin Jinhan .of_match = rockchip_crypto_ids, 1523b353a43cSLin Jinhan .ops = &rockchip_crypto_ops, 1524b353a43cSLin Jinhan .probe = rockchip_crypto_probe, 1525b353a43cSLin Jinhan .ofdata_to_platdata = rockchip_crypto_ofdata_to_platdata, 1526b353a43cSLin Jinhan .priv_auto_alloc_size = sizeof(struct rockchip_crypto_priv), 1527b353a43cSLin Jinhan }; 1528