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 || \ 108*c3ce9937SLin Jinhan (rk_mode) == RK_MODE_CBC_MAC || \ 109*c3ce9937SLin Jinhan (rk_mode) == RK_MODE_CCM || \ 110*c3ce9937SLin 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 115*c3ce9937SLin Jinhan #define IS_AE_MODE(rk_mode) ((rk_mode) == RK_MODE_CCM || \ 116*c3ce9937SLin Jinhan (rk_mode) == RK_MODE_GCM) 117*c3ce9937SLin 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 152*c3ce9937SLin Jinhan static inline void read_regs(u32 base, u8 *data, u32 data_len) 153*c3ce9937SLin Jinhan { 154*c3ce9937SLin Jinhan u8 tmp_buf[4]; 155*c3ce9937SLin Jinhan u32 i; 156*c3ce9937SLin Jinhan 157*c3ce9937SLin Jinhan for (i = 0; i < data_len / 4; i++) 158*c3ce9937SLin Jinhan word2byte_be(crypto_read(base + i * 4), 159*c3ce9937SLin Jinhan data + i * 4); 160*c3ce9937SLin Jinhan 161*c3ce9937SLin Jinhan if (data_len % 4) { 162*c3ce9937SLin Jinhan word2byte_be(crypto_read(base + i * 4), tmp_buf); 163*c3ce9937SLin Jinhan memcpy(data + i * 4, tmp_buf, data_len % 4); 164*c3ce9937SLin Jinhan } 165*c3ce9937SLin Jinhan } 166*c3ce9937SLin 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 204*c3ce9937SLin Jinhan static inline void get_iv_reg(u32 chn, u8 *iv, u32 iv_len) 205*c3ce9937SLin Jinhan { 206*c3ce9937SLin Jinhan u32 base_iv; 207*c3ce9937SLin Jinhan 208*c3ce9937SLin Jinhan base_iv = CRYPTO_CH0_IV_0 + chn * 0x10; 209*c3ce9937SLin Jinhan 210*c3ce9937SLin Jinhan read_regs(base_iv, iv, iv_len); 211*c3ce9937SLin Jinhan } 212*c3ce9937SLin 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 439*c3ce9937SLin 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, 615*c3ce9937SLin Jinhan [RK_MODE_CCM] = CRYPTO_BC_CCM, 616*c3ce9937SLin 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 621*c3ce9937SLin Jinhan static inline void set_pc_len_reg(u32 chn, u64 pc_len) 622*c3ce9937SLin Jinhan { 623*c3ce9937SLin Jinhan u32 chn_base = CRYPTO_CH0_PC_LEN_0 + chn * 0x08; 624*c3ce9937SLin Jinhan 625*c3ce9937SLin Jinhan crypto_write(pc_len & 0xffffffff, chn_base); 626*c3ce9937SLin Jinhan crypto_write(pc_len >> 32, chn_base + 4); 627*c3ce9937SLin Jinhan } 628*c3ce9937SLin Jinhan 629*c3ce9937SLin Jinhan static inline void set_aad_len_reg(u32 chn, u64 pc_len) 630*c3ce9937SLin Jinhan { 631*c3ce9937SLin Jinhan u32 chn_base = CRYPTO_CH0_AAD_LEN_0 + chn * 0x08; 632*c3ce9937SLin Jinhan 633*c3ce9937SLin Jinhan crypto_write(pc_len & 0xffffffff, chn_base); 634*c3ce9937SLin Jinhan crypto_write(pc_len >> 32, chn_base + 4); 635*c3ce9937SLin Jinhan } 636*c3ce9937SLin 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 64549a2135eSLin Jinhan static void dump_crypto_state(struct crypto_lli_desc *desc, int ret) 64649a2135eSLin Jinhan { 64749a2135eSLin Jinhan IMSG("%s\n", ret == -ETIME ? "timeout" : "dismatch"); 64849a2135eSLin Jinhan 64949a2135eSLin Jinhan IMSG("CRYPTO_DMA_INT_ST = %08x, expect_int = %08x\n", 65049a2135eSLin Jinhan tmp, expt_int); 65149a2135eSLin Jinhan IMSG("data desc = %p\n", desc); 65249a2135eSLin Jinhan IMSG("\taddr_in = [%08x <=> %08x]\n", 65349a2135eSLin Jinhan desc->src_addr, (u32)virt_to_phys(in)); 65449a2135eSLin Jinhan IMSG("\taddr_out = [%08x <=> %08x]\n", 65549a2135eSLin Jinhan desc->dst_addr, (u32)virt_to_phys(out)); 65649a2135eSLin Jinhan IMSG("\tsrc_len = [%08x <=> %08x]\n", 65749a2135eSLin Jinhan desc->src_len, (u32)len); 65849a2135eSLin Jinhan IMSG("\tdst_len = %08x\n", desc->dst_len); 65949a2135eSLin Jinhan IMSG("\tdma_ctl = %08x\n", desc->dma_ctrl); 66049a2135eSLin Jinhan IMSG("\tuser_define = %08x\n", desc->user_define); 66149a2135eSLin Jinhan 66249a2135eSLin Jinhan IMSG("\n\nDMA CRYPTO_DMA_LLI_ADDR status = %08x\n", 66349a2135eSLin Jinhan crypto_read(CRYPTO_DMA_LLI_ADDR)); 66449a2135eSLin Jinhan IMSG("DMA CRYPTO_DMA_ST status = %08x\n", 66549a2135eSLin Jinhan crypto_read(CRYPTO_DMA_ST)); 66649a2135eSLin Jinhan IMSG("DMA CRYPTO_DMA_STATE status = %08x\n", 66749a2135eSLin Jinhan crypto_read(CRYPTO_DMA_STATE)); 66849a2135eSLin Jinhan IMSG("DMA CRYPTO_DMA_LLI_RADDR status = %08x\n", 66949a2135eSLin Jinhan crypto_read(CRYPTO_DMA_LLI_RADDR)); 67049a2135eSLin Jinhan IMSG("DMA CRYPTO_DMA_SRC_RADDR status = %08x\n", 67149a2135eSLin Jinhan crypto_read(CRYPTO_DMA_SRC_RADDR)); 67249a2135eSLin Jinhan IMSG("DMA CRYPTO_DMA_DST_RADDR status = %08x\n", 67349a2135eSLin Jinhan crypto_read(CRYPTO_DMA_DST_RADDR)); 67449a2135eSLin Jinhan IMSG("DMA CRYPTO_CIPHER_ST status = %08x\n", 67549a2135eSLin Jinhan crypto_read(CRYPTO_CIPHER_ST)); 67649a2135eSLin Jinhan IMSG("DMA CRYPTO_CIPHER_STATE status = %08x\n", 67749a2135eSLin Jinhan crypto_read(CRYPTO_CIPHER_STATE)); 67849a2135eSLin Jinhan IMSG("DMA CRYPTO_TAG_VALID status = %08x\n", 67949a2135eSLin Jinhan crypto_read(CRYPTO_TAG_VALID)); 68049a2135eSLin Jinhan IMSG("LOCKSTEP status = %08x\n\n", 68149a2135eSLin Jinhan crypto_read(0x618)); 68249a2135eSLin Jinhan 68349a2135eSLin Jinhan IMSG("dst %dbyte not transferred\n", 68449a2135eSLin Jinhan desc->dst_addr + desc->dst_len - 68549a2135eSLin Jinhan crypto_read(CRYPTO_DMA_DST_RADDR)); 68649a2135eSLin Jinhan } 68749a2135eSLin Jinhan 688*c3ce9937SLin Jinhan static int ccm128_set_iv_reg(u32 chn, const u8 *nonce, u32 nlen) 689*c3ce9937SLin Jinhan { 690*c3ce9937SLin Jinhan u8 iv_buf[AES_BLOCK_SIZE]; 691*c3ce9937SLin Jinhan u32 L; 692*c3ce9937SLin Jinhan 693*c3ce9937SLin Jinhan memset(iv_buf, 0x00, sizeof(iv_buf)); 694*c3ce9937SLin Jinhan 695*c3ce9937SLin Jinhan L = 15 - nlen; 696*c3ce9937SLin Jinhan iv_buf[0] = ((u8)(L - 1) & 7); 697*c3ce9937SLin Jinhan 698*c3ce9937SLin Jinhan /* the L parameter */ 699*c3ce9937SLin Jinhan L = iv_buf[0] & 7; 700*c3ce9937SLin Jinhan 701*c3ce9937SLin Jinhan /* nonce is too short */ 702*c3ce9937SLin Jinhan if (nlen < (14 - L)) 703*c3ce9937SLin Jinhan return -EINVAL; 704*c3ce9937SLin Jinhan 705*c3ce9937SLin Jinhan /* clear aad flag */ 706*c3ce9937SLin Jinhan iv_buf[0] &= ~0x40; 707*c3ce9937SLin Jinhan memcpy(&iv_buf[1], nonce, 14 - L); 708*c3ce9937SLin Jinhan 709*c3ce9937SLin Jinhan set_iv_reg(chn, iv_buf, AES_BLOCK_SIZE); 710*c3ce9937SLin Jinhan 711*c3ce9937SLin Jinhan return 0; 712*c3ce9937SLin Jinhan } 713*c3ce9937SLin Jinhan 714*c3ce9937SLin Jinhan static void ccm_aad_padding(u32 aad_len, u8 *padding, u32 *padding_size) 715*c3ce9937SLin Jinhan { 716*c3ce9937SLin Jinhan u32 i; 717*c3ce9937SLin Jinhan 718*c3ce9937SLin Jinhan i = aad_len < (0x10000 - 0x100) ? 2 : 6; 719*c3ce9937SLin Jinhan 720*c3ce9937SLin Jinhan if (i == 2) { 721*c3ce9937SLin Jinhan padding[0] = (u8)(aad_len >> 8); 722*c3ce9937SLin Jinhan padding[1] = (u8)aad_len; 723*c3ce9937SLin Jinhan } else { 724*c3ce9937SLin Jinhan padding[0] = 0xFF; 725*c3ce9937SLin Jinhan padding[1] = 0xFE; 726*c3ce9937SLin Jinhan padding[2] = (u8)(aad_len >> 24); 727*c3ce9937SLin Jinhan padding[3] = (u8)(aad_len >> 16); 728*c3ce9937SLin Jinhan padding[4] = (u8)(aad_len >> 8); 729*c3ce9937SLin Jinhan } 730*c3ce9937SLin Jinhan 731*c3ce9937SLin Jinhan *padding_size = i; 732*c3ce9937SLin Jinhan } 733*c3ce9937SLin Jinhan 734*c3ce9937SLin Jinhan static int ccm_compose_aad_iv(u8 *aad_iv, u32 data_len, u32 tag_size) 735*c3ce9937SLin Jinhan { 736*c3ce9937SLin Jinhan aad_iv[0] |= ((u8)(((tag_size - 2) / 2) & 7) << 3); 737*c3ce9937SLin Jinhan 738*c3ce9937SLin Jinhan aad_iv[12] = (u8)(data_len >> 24); 739*c3ce9937SLin Jinhan aad_iv[13] = (u8)(data_len >> 16); 740*c3ce9937SLin Jinhan aad_iv[14] = (u8)(data_len >> 8); 741*c3ce9937SLin Jinhan aad_iv[15] = (u8)data_len; 742*c3ce9937SLin Jinhan 743*c3ce9937SLin Jinhan aad_iv[0] |= 0x40; //set aad flag 744*c3ce9937SLin Jinhan 745*c3ce9937SLin Jinhan return 0; 746*c3ce9937SLin Jinhan } 747*c3ce9937SLin Jinhan 74849a2135eSLin Jinhan static int hw_cipher_init(u32 chn, const u8 *key, const u8 *twk_key, 74949a2135eSLin Jinhan u32 key_len, const u8 *iv, u32 iv_len, 75049a2135eSLin Jinhan u32 algo, u32 mode, bool enc) 75149a2135eSLin Jinhan { 75249a2135eSLin Jinhan u32 rk_mode = RK_GET_RK_MODE(mode); 75349a2135eSLin Jinhan u32 key_chn_sel = chn; 75449a2135eSLin Jinhan u32 reg_ctrl = 0; 75549a2135eSLin Jinhan 75649a2135eSLin Jinhan IMSG("%s: key addr is %p, key_len is %d, iv addr is %p", 75749a2135eSLin Jinhan __func__, key, key_len, iv); 75849a2135eSLin Jinhan if (rk_mode >= RK_MODE_MAX) 75949a2135eSLin Jinhan return -EINVAL; 76049a2135eSLin Jinhan 76149a2135eSLin Jinhan switch (algo) { 76249a2135eSLin Jinhan case CRYPTO_DES: 76349a2135eSLin Jinhan if (key_len > DES_BLOCK_SIZE) 76449a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_TDES; 76549a2135eSLin Jinhan else 76649a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_DES; 76749a2135eSLin Jinhan break; 76849a2135eSLin Jinhan case CRYPTO_AES: 76949a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_AES; 77049a2135eSLin Jinhan break; 77149a2135eSLin Jinhan case CRYPTO_SM4: 77249a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_SM4; 77349a2135eSLin Jinhan break; 77449a2135eSLin Jinhan default: 77549a2135eSLin Jinhan return -EINVAL; 77649a2135eSLin Jinhan } 77749a2135eSLin Jinhan 77849a2135eSLin Jinhan if (algo == CRYPTO_AES || algo == CRYPTO_SM4) { 77949a2135eSLin Jinhan switch (key_len) { 78049a2135eSLin Jinhan case AES_KEYSIZE_128: 78149a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_128_bit_key; 78249a2135eSLin Jinhan break; 78349a2135eSLin Jinhan case AES_KEYSIZE_192: 78449a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_192_bit_key; 78549a2135eSLin Jinhan break; 78649a2135eSLin Jinhan case AES_KEYSIZE_256: 78749a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_256_bit_key; 78849a2135eSLin Jinhan break; 78949a2135eSLin Jinhan default: 79049a2135eSLin Jinhan return -EINVAL; 79149a2135eSLin Jinhan } 79249a2135eSLin Jinhan } 79349a2135eSLin Jinhan 79449a2135eSLin Jinhan reg_ctrl |= rk_mode2bc_mode[rk_mode]; 79549a2135eSLin Jinhan if (!enc) 79649a2135eSLin Jinhan reg_ctrl |= CRYPTO_BC_DECRYPT; 79749a2135eSLin Jinhan 79849a2135eSLin Jinhan /* write key data to reg */ 79949a2135eSLin Jinhan write_key_reg(key_chn_sel, key, key_len); 80049a2135eSLin Jinhan 80149a2135eSLin Jinhan /* write twk key for xts mode */ 80249a2135eSLin Jinhan if (rk_mode == RK_MODE_XTS) 80349a2135eSLin Jinhan write_key_reg(key_chn_sel + 4, twk_key, key_len); 80449a2135eSLin Jinhan 80549a2135eSLin Jinhan /* set iv reg */ 806*c3ce9937SLin Jinhan if (rk_mode == RK_MODE_CCM) 807*c3ce9937SLin Jinhan ccm128_set_iv_reg(chn, iv, iv_len); 808*c3ce9937SLin Jinhan else 80949a2135eSLin Jinhan set_iv_reg(chn, iv, iv_len); 81049a2135eSLin Jinhan 81149a2135eSLin Jinhan /* din_swap set 1, dout_swap set 1, default 1. */ 81249a2135eSLin Jinhan crypto_write(0x00030003, CRYPTO_FIFO_CTL); 81349a2135eSLin Jinhan crypto_write(CRYPTO_LIST_DONE_INT_EN | CRYPTO_DST_ITEM_DONE_INT_EN, 81449a2135eSLin Jinhan CRYPTO_DMA_INT_EN); 81549a2135eSLin Jinhan 81649a2135eSLin Jinhan crypto_write(reg_ctrl | CRYPTO_WRITE_MASK_ALL, CRYPTO_BC_CTL); 81749a2135eSLin Jinhan 81849a2135eSLin Jinhan return 0; 81949a2135eSLin Jinhan } 82049a2135eSLin Jinhan 82149a2135eSLin Jinhan static int hw_cipher_crypt(const u8 *in, u8 *out, u64 len, 822*c3ce9937SLin Jinhan const u8 *aad, u32 aad_len, 823*c3ce9937SLin Jinhan u8 *tag, u32 tag_len, u32 mode) 82449a2135eSLin Jinhan { 825*c3ce9937SLin Jinhan struct crypto_lli_desc *data_desc = NULL, *aad_desc = NULL; 826*c3ce9937SLin Jinhan u8 *dma_in = NULL, *dma_out = NULL, *aad_tmp = NULL; 82749a2135eSLin Jinhan u32 rk_mode = RK_GET_RK_MODE(mode); 82849a2135eSLin Jinhan u32 reg_ctrl = 0, tmp_len = 0; 82949a2135eSLin Jinhan u32 expt_int = 0, mask = 0; 83049a2135eSLin Jinhan u32 key_chn = g_key_chn; 83149a2135eSLin Jinhan u32 tmp, dst_len = 0; 83249a2135eSLin Jinhan int ret = -1; 83349a2135eSLin Jinhan 83449a2135eSLin Jinhan if (rk_mode == RK_MODE_CTS && len <= AES_BLOCK_SIZE) { 83549a2135eSLin Jinhan printf("CTS mode length %u < 16Byte\n", (u32)len); 83649a2135eSLin Jinhan return -EINVAL; 83749a2135eSLin Jinhan } 83849a2135eSLin Jinhan 83949a2135eSLin Jinhan tmp_len = (rk_mode == RK_MODE_CTR) ? ROUNDUP(len, AES_BLOCK_SIZE) : len; 84049a2135eSLin Jinhan 84149a2135eSLin Jinhan data_desc = align_malloc(sizeof(*data_desc), LLI_ADDR_ALIGN_SIZE); 84249a2135eSLin Jinhan if (!data_desc) 84349a2135eSLin Jinhan goto exit; 84449a2135eSLin Jinhan 84549a2135eSLin Jinhan if (IS_ALIGNED((ulong)in, DATA_ADDR_ALIGN_SIZE) && tmp_len == len) 84649a2135eSLin Jinhan dma_in = (void *)in; 84749a2135eSLin Jinhan else 84849a2135eSLin Jinhan dma_in = align_malloc(tmp_len, DATA_ADDR_ALIGN_SIZE); 84949a2135eSLin Jinhan if (!dma_in) 85049a2135eSLin Jinhan goto exit; 85149a2135eSLin Jinhan 85249a2135eSLin Jinhan if (out) { 85349a2135eSLin Jinhan if (IS_ALIGNED((ulong)out, DATA_ADDR_ALIGN_SIZE) && 85449a2135eSLin Jinhan tmp_len == len) 85549a2135eSLin Jinhan dma_out = out; 85649a2135eSLin Jinhan else 85749a2135eSLin Jinhan dma_out = align_malloc(tmp_len, DATA_ADDR_ALIGN_SIZE); 85849a2135eSLin Jinhan if (!dma_out) 85949a2135eSLin Jinhan goto exit; 86049a2135eSLin Jinhan dst_len = tmp_len; 86149a2135eSLin Jinhan } 86249a2135eSLin Jinhan 86349a2135eSLin Jinhan memset(data_desc, 0x00, sizeof(*data_desc)); 86449a2135eSLin Jinhan if (dma_in != in) 86549a2135eSLin Jinhan memcpy(dma_in, in, len); 86649a2135eSLin Jinhan 86749a2135eSLin Jinhan data_desc->src_addr = (u32)virt_to_phys(dma_in); 86849a2135eSLin Jinhan data_desc->src_len = tmp_len; 86949a2135eSLin Jinhan data_desc->dst_addr = (u32)virt_to_phys(dma_out); 87049a2135eSLin Jinhan data_desc->dst_len = dst_len; 871d9332f1cSLin Jinhan data_desc->dma_ctrl = LLI_DMA_CTRL_LAST; 872d9332f1cSLin Jinhan 873d9332f1cSLin Jinhan if (IS_MAC_MODE(rk_mode)) { 874d9332f1cSLin Jinhan expt_int = CRYPTO_LIST_DONE_INT_ST; 875d9332f1cSLin Jinhan data_desc->dma_ctrl |= LLI_DMA_CTRL_LIST_DONE; 876d9332f1cSLin Jinhan } else { 87749a2135eSLin Jinhan expt_int = CRYPTO_DST_ITEM_DONE_INT_ST; 878d9332f1cSLin Jinhan data_desc->dma_ctrl |= LLI_DMA_CTRL_DST_DONE; 879d9332f1cSLin Jinhan } 88049a2135eSLin Jinhan 881*c3ce9937SLin Jinhan if (rk_mode == RK_MODE_CCM || rk_mode == RK_MODE_GCM) { 882*c3ce9937SLin Jinhan u32 aad_tmp_len = 0; 883*c3ce9937SLin Jinhan 884*c3ce9937SLin Jinhan data_desc->user_define = LLI_USER_STRING_START | 885*c3ce9937SLin Jinhan LLI_USER_STRING_LAST | 886*c3ce9937SLin Jinhan (key_chn << 4); 887*c3ce9937SLin Jinhan 888*c3ce9937SLin Jinhan aad_desc = align_malloc(sizeof(*aad_desc), LLI_ADDR_ALIGN_SIZE); 889*c3ce9937SLin Jinhan if (!aad_desc) 890*c3ce9937SLin Jinhan goto exit; 891*c3ce9937SLin Jinhan 892*c3ce9937SLin Jinhan memset(aad_desc, 0x00, sizeof(*aad_desc)); 893*c3ce9937SLin Jinhan aad_desc->next_addr = (u32)virt_to_phys(data_desc); 894*c3ce9937SLin Jinhan aad_desc->user_define = LLI_USER_CPIHER_START | 895*c3ce9937SLin Jinhan LLI_USER_STRING_START | 896*c3ce9937SLin Jinhan LLI_USER_STRING_LAST | 897*c3ce9937SLin Jinhan LLI_USER_STRING_AAD | 898*c3ce9937SLin Jinhan (key_chn << 4); 899*c3ce9937SLin Jinhan 900*c3ce9937SLin Jinhan if (rk_mode == RK_MODE_CCM) { 901*c3ce9937SLin Jinhan u8 padding[AES_BLOCK_SIZE]; 902*c3ce9937SLin Jinhan u32 padding_size = 0; 903*c3ce9937SLin Jinhan 904*c3ce9937SLin Jinhan memset(padding, 0x00, sizeof(padding)); 905*c3ce9937SLin Jinhan ccm_aad_padding(aad_len, padding, &padding_size); 906*c3ce9937SLin Jinhan 907*c3ce9937SLin Jinhan aad_tmp_len = aad_len + AES_BLOCK_SIZE + padding_size; 908*c3ce9937SLin Jinhan aad_tmp_len = ROUNDUP(aad_tmp_len, AES_BLOCK_SIZE); 909*c3ce9937SLin Jinhan aad_tmp = align_malloc(aad_tmp_len, 910*c3ce9937SLin Jinhan DATA_ADDR_ALIGN_SIZE); 911*c3ce9937SLin Jinhan if (!aad_tmp) 912*c3ce9937SLin Jinhan goto exit; 913*c3ce9937SLin Jinhan 914*c3ce9937SLin Jinhan /* read iv data from reg */ 915*c3ce9937SLin Jinhan get_iv_reg(key_chn, aad_tmp, AES_BLOCK_SIZE); 916*c3ce9937SLin Jinhan ccm_compose_aad_iv(aad_tmp, tmp_len, tag_len); 917*c3ce9937SLin Jinhan memcpy(aad_tmp + AES_BLOCK_SIZE, padding, padding_size); 918*c3ce9937SLin Jinhan memset(aad_tmp + aad_tmp_len - AES_BLOCK_SIZE, 919*c3ce9937SLin Jinhan 0x00, AES_BLOCK_SIZE); 920*c3ce9937SLin Jinhan memcpy(aad_tmp + AES_BLOCK_SIZE + padding_size, 921*c3ce9937SLin Jinhan aad, aad_len); 922*c3ce9937SLin Jinhan } else { 923*c3ce9937SLin Jinhan aad_tmp_len = aad_len; 924*c3ce9937SLin Jinhan aad_tmp = align_malloc(aad_tmp_len, 925*c3ce9937SLin Jinhan DATA_ADDR_ALIGN_SIZE); 926*c3ce9937SLin Jinhan if (!aad_tmp) 927*c3ce9937SLin Jinhan goto exit; 928*c3ce9937SLin Jinhan 929*c3ce9937SLin Jinhan memcpy(aad_tmp, aad, aad_tmp_len); 930*c3ce9937SLin Jinhan set_aad_len_reg(key_chn, aad_tmp_len); 931*c3ce9937SLin Jinhan set_pc_len_reg(key_chn, tmp_len); 932*c3ce9937SLin Jinhan } 933*c3ce9937SLin Jinhan 934*c3ce9937SLin Jinhan aad_desc->src_addr = (u32)virt_to_phys(aad_tmp); 935*c3ce9937SLin Jinhan aad_desc->src_len = aad_tmp_len; 936*c3ce9937SLin Jinhan crypto_write((u32)virt_to_phys(aad_desc), CRYPTO_DMA_LLI_ADDR); 937*c3ce9937SLin Jinhan cache_op_inner(DCACHE_AREA_CLEAN, aad_tmp, aad_tmp_len); 938*c3ce9937SLin Jinhan cache_op_inner(DCACHE_AREA_CLEAN, aad_desc, sizeof(*aad_desc)); 939*c3ce9937SLin Jinhan } else { 940*c3ce9937SLin Jinhan data_desc->user_define = LLI_USER_CPIHER_START | 941*c3ce9937SLin Jinhan LLI_USER_STRING_START | 942*c3ce9937SLin Jinhan LLI_USER_STRING_LAST | 943*c3ce9937SLin Jinhan (key_chn << 4); 94449a2135eSLin Jinhan crypto_write((u32)virt_to_phys(data_desc), CRYPTO_DMA_LLI_ADDR); 945*c3ce9937SLin Jinhan } 94649a2135eSLin Jinhan 94749a2135eSLin Jinhan cache_op_inner(DCACHE_AREA_CLEAN, data_desc, sizeof(*data_desc)); 94849a2135eSLin Jinhan cache_op_inner(DCACHE_AREA_CLEAN, dma_in, tmp_len); 94949a2135eSLin Jinhan cache_op_inner(DCACHE_AREA_INVALIDATE, dma_out, tmp_len); 95049a2135eSLin Jinhan 95149a2135eSLin Jinhan /* din_swap set 1, dout_swap set 1, default 1. */ 95249a2135eSLin Jinhan crypto_write(0x00030003, CRYPTO_FIFO_CTL); 95349a2135eSLin Jinhan crypto_write(CRYPTO_DST_ITEM_DONE_INT_EN | CRYPTO_LIST_DONE_INT_EN, 95449a2135eSLin Jinhan CRYPTO_DMA_INT_EN); 95549a2135eSLin Jinhan 95649a2135eSLin Jinhan reg_ctrl = crypto_read(CRYPTO_BC_CTL) | CRYPTO_BC_ENABLE; 95749a2135eSLin Jinhan crypto_write(reg_ctrl | CRYPTO_WRITE_MASK_ALL, CRYPTO_BC_CTL); 95849a2135eSLin Jinhan crypto_write(0x00010001, CRYPTO_DMA_CTL);//start 95949a2135eSLin Jinhan 96049a2135eSLin Jinhan mask = ~(mask | CRYPTO_SYNC_LOCKSTEP_INT_ST); 96149a2135eSLin Jinhan 96249a2135eSLin Jinhan /* wait calc ok */ 96349a2135eSLin Jinhan ret = RK_POLL_TIMEOUT(!(crypto_read(CRYPTO_DMA_INT_ST) & mask), 96449a2135eSLin Jinhan RK_CRYPTO_TIMEOUT); 96549a2135eSLin Jinhan tmp = crypto_read(CRYPTO_DMA_INT_ST); 96649a2135eSLin Jinhan crypto_write(tmp, CRYPTO_DMA_INT_ST); 96749a2135eSLin Jinhan 96849a2135eSLin Jinhan if ((tmp & mask) == expt_int) { 96949a2135eSLin Jinhan if (out && out != dma_out) 97049a2135eSLin Jinhan memcpy(out, dma_out, len); 971d9332f1cSLin Jinhan 972d9332f1cSLin Jinhan if (IS_NEED_TAG(rk_mode)) { 973d9332f1cSLin Jinhan ret = WAIT_TAG_VALID(key_chn, RK_CRYPTO_TIMEOUT); 974d9332f1cSLin Jinhan get_tag_from_reg(key_chn, tag, AES_BLOCK_SIZE); 975d9332f1cSLin Jinhan } 97649a2135eSLin Jinhan } else { 97749a2135eSLin Jinhan dump_crypto_state(data_desc, ret); 97849a2135eSLin Jinhan ret = -1; 97949a2135eSLin Jinhan } 98049a2135eSLin Jinhan 98149a2135eSLin Jinhan exit: 98249a2135eSLin Jinhan crypto_write(0xffff0000, CRYPTO_BC_CTL);//bc_ctl disable 98349a2135eSLin Jinhan align_free(data_desc); 984*c3ce9937SLin Jinhan align_free(aad_desc); 98549a2135eSLin Jinhan if (dma_in && dma_in != in) 98649a2135eSLin Jinhan align_free(dma_in); 98749a2135eSLin Jinhan if (dma_out && dma_out != out) 98849a2135eSLin Jinhan align_free(dma_out); 98949a2135eSLin Jinhan 99049a2135eSLin Jinhan return ret; 99149a2135eSLin Jinhan } 99249a2135eSLin Jinhan 99349a2135eSLin Jinhan static int hw_aes_init(u32 chn, const u8 *key, const u8 *twk_key, u32 key_len, 99449a2135eSLin Jinhan const u8 *iv, u32 iv_len, u32 mode, bool enc) 99549a2135eSLin Jinhan { 99649a2135eSLin Jinhan u32 rk_mode = RK_GET_RK_MODE(mode); 99749a2135eSLin Jinhan 998d9332f1cSLin Jinhan if (rk_mode > RK_MODE_XTS) 999d9332f1cSLin Jinhan return -EINVAL; 1000d9332f1cSLin Jinhan 100149a2135eSLin Jinhan if (iv_len > AES_BLOCK_SIZE) 100249a2135eSLin Jinhan return -EINVAL; 100349a2135eSLin Jinhan 1004d9332f1cSLin Jinhan if (IS_NEED_IV(rk_mode)) { 100549a2135eSLin Jinhan if (!iv || iv_len != AES_BLOCK_SIZE) 100649a2135eSLin Jinhan return -EINVAL; 100749a2135eSLin Jinhan } else { 100849a2135eSLin Jinhan iv_len = 0; 100949a2135eSLin Jinhan } 101049a2135eSLin Jinhan 101149a2135eSLin Jinhan if (rk_mode == RK_MODE_XTS) { 101249a2135eSLin Jinhan if (key_len != AES_KEYSIZE_128 && key_len != AES_KEYSIZE_256) 101349a2135eSLin Jinhan return -EINVAL; 101449a2135eSLin Jinhan 101549a2135eSLin Jinhan if (!key || !twk_key) 101649a2135eSLin Jinhan return -EINVAL; 101749a2135eSLin Jinhan } else { 101849a2135eSLin Jinhan if (key_len != AES_KEYSIZE_128 && 101949a2135eSLin Jinhan key_len != AES_KEYSIZE_192 && 102049a2135eSLin Jinhan key_len != AES_KEYSIZE_256) 102149a2135eSLin Jinhan return -EINVAL; 102249a2135eSLin Jinhan } 102349a2135eSLin Jinhan 102449a2135eSLin Jinhan return hw_cipher_init(chn, key, twk_key, key_len, iv, iv_len, 102549a2135eSLin Jinhan CRYPTO_AES, mode, enc); 102649a2135eSLin Jinhan } 102749a2135eSLin Jinhan 102849a2135eSLin Jinhan static int hw_sm4_init(u32 chn, const u8 *key, const u8 *twk_key, u32 key_len, 102949a2135eSLin Jinhan const u8 *iv, u32 iv_len, u32 mode, bool enc) 103049a2135eSLin Jinhan { 103149a2135eSLin Jinhan u32 rk_mode = RK_GET_RK_MODE(mode); 103249a2135eSLin Jinhan 1033d9332f1cSLin Jinhan if (rk_mode > RK_MODE_XTS) 1034d9332f1cSLin Jinhan return -EINVAL; 1035d9332f1cSLin Jinhan 103649a2135eSLin Jinhan if (iv_len > SM4_BLOCK_SIZE || key_len != SM4_KEYSIZE) 103749a2135eSLin Jinhan return -EINVAL; 103849a2135eSLin Jinhan 1039d9332f1cSLin Jinhan if (IS_NEED_IV(rk_mode)) { 104049a2135eSLin Jinhan if (!iv || iv_len != SM4_BLOCK_SIZE) 104149a2135eSLin Jinhan return -EINVAL; 104249a2135eSLin Jinhan } else { 104349a2135eSLin Jinhan iv_len = 0; 104449a2135eSLin Jinhan } 104549a2135eSLin Jinhan 104649a2135eSLin Jinhan if (rk_mode == RK_MODE_XTS) { 104749a2135eSLin Jinhan if (!key || !twk_key) 104849a2135eSLin Jinhan return -EINVAL; 104949a2135eSLin Jinhan } 105049a2135eSLin Jinhan 105149a2135eSLin Jinhan return hw_cipher_init(chn, key, twk_key, key_len, iv, iv_len, 105249a2135eSLin Jinhan CRYPTO_SM4, mode, enc); 105349a2135eSLin Jinhan } 105449a2135eSLin Jinhan 105549a2135eSLin Jinhan int rk_crypto_des(struct udevice *dev, u32 mode, const u8 *key, u32 key_len, 105649a2135eSLin Jinhan const u8 *iv, const u8 *in, u8 *out, u32 len, bool enc) 105749a2135eSLin Jinhan { 105849a2135eSLin Jinhan u32 rk_mode = RK_GET_RK_MODE(mode); 105949a2135eSLin Jinhan u8 tmp_key[24]; 106049a2135eSLin Jinhan int ret; 106149a2135eSLin Jinhan 106249a2135eSLin Jinhan if (!is_des_mode(rk_mode)) 106349a2135eSLin Jinhan return -EINVAL; 106449a2135eSLin Jinhan 106549a2135eSLin Jinhan if (key_len == DES_BLOCK_SIZE || key_len == 3 * DES_BLOCK_SIZE) { 106649a2135eSLin Jinhan memcpy(tmp_key, key, key_len); 106749a2135eSLin Jinhan } else if (key_len == 2 * DES_BLOCK_SIZE) { 106849a2135eSLin Jinhan memcpy(tmp_key, key, 16); 106949a2135eSLin Jinhan memcpy(tmp_key + 16, key, 8); 107049a2135eSLin Jinhan key_len = 3 * DES_BLOCK_SIZE; 107149a2135eSLin Jinhan } else { 107249a2135eSLin Jinhan return -EINVAL; 107349a2135eSLin Jinhan } 107449a2135eSLin Jinhan 107549a2135eSLin Jinhan ret = hw_cipher_init(0, tmp_key, NULL, key_len, iv, DES_BLOCK_SIZE, 107649a2135eSLin Jinhan CRYPTO_DES, mode, enc); 107749a2135eSLin Jinhan if (ret) 107849a2135eSLin Jinhan goto exit; 107949a2135eSLin Jinhan 108049a2135eSLin Jinhan ret = hw_cipher_crypt(in, out, len, NULL, 0, 108149a2135eSLin Jinhan NULL, 0, mode); 108249a2135eSLin Jinhan 108349a2135eSLin Jinhan exit: 108449a2135eSLin Jinhan return ret; 108549a2135eSLin Jinhan } 108649a2135eSLin Jinhan 108749a2135eSLin Jinhan int rk_crypto_aes(struct udevice *dev, u32 mode, 108849a2135eSLin Jinhan const u8 *key, const u8 *twk_key, u32 key_len, 108949a2135eSLin Jinhan const u8 *iv, u32 iv_len, 109049a2135eSLin Jinhan const u8 *in, u8 *out, u32 len, bool enc) 109149a2135eSLin Jinhan { 109249a2135eSLin Jinhan int ret; 109349a2135eSLin Jinhan 109449a2135eSLin Jinhan /* RV1126/RV1109 do not support aes-192 */ 109549a2135eSLin Jinhan #if defined(CONFIG_ROCKCHIP_RV1126) 109649a2135eSLin Jinhan if (key_len == AES_KEYSIZE_192) 109749a2135eSLin Jinhan return -EINVAL; 109849a2135eSLin Jinhan #endif 109949a2135eSLin Jinhan 110049a2135eSLin Jinhan ret = hw_aes_init(0, key, twk_key, key_len, iv, iv_len, mode, enc); 110149a2135eSLin Jinhan if (ret) 110249a2135eSLin Jinhan return ret; 110349a2135eSLin Jinhan 110449a2135eSLin Jinhan return hw_cipher_crypt(in, out, len, NULL, 0, 110549a2135eSLin Jinhan NULL, 0, mode); 110649a2135eSLin Jinhan } 110749a2135eSLin Jinhan 110849a2135eSLin Jinhan int rk_crypto_sm4(struct udevice *dev, u32 mode, 110949a2135eSLin Jinhan const u8 *key, const u8 *twk_key, u32 key_len, 111049a2135eSLin Jinhan const u8 *iv, u32 iv_len, 111149a2135eSLin Jinhan const u8 *in, u8 *out, u32 len, bool enc) 111249a2135eSLin Jinhan { 111349a2135eSLin Jinhan int ret; 111449a2135eSLin Jinhan 111549a2135eSLin Jinhan ret = hw_sm4_init(0, key, twk_key, key_len, iv, iv_len, mode, enc); 111649a2135eSLin Jinhan if (ret) 111749a2135eSLin Jinhan return ret; 111849a2135eSLin Jinhan 111949a2135eSLin Jinhan return hw_cipher_crypt(in, out, len, NULL, 0, NULL, 0, mode); 112049a2135eSLin Jinhan } 112149a2135eSLin Jinhan 112249a2135eSLin Jinhan int rockchip_crypto_cipher(struct udevice *dev, cipher_context *ctx, 112349a2135eSLin Jinhan const u8 *in, u8 *out, u32 len, bool enc) 112449a2135eSLin Jinhan { 112549a2135eSLin Jinhan switch (ctx->algo) { 112649a2135eSLin Jinhan case CRYPTO_DES: 112749a2135eSLin Jinhan return rk_crypto_des(dev, ctx->mode, ctx->key, ctx->key_len, 112849a2135eSLin Jinhan ctx->iv, in, out, len, enc); 112949a2135eSLin Jinhan case CRYPTO_AES: 113049a2135eSLin Jinhan return rk_crypto_aes(dev, ctx->mode, 113149a2135eSLin Jinhan ctx->key, ctx->twk_key, ctx->key_len, 113249a2135eSLin Jinhan ctx->iv, ctx->iv_len, in, out, len, enc); 113349a2135eSLin Jinhan case CRYPTO_SM4: 113449a2135eSLin Jinhan return rk_crypto_sm4(dev, ctx->mode, 113549a2135eSLin Jinhan ctx->key, ctx->twk_key, ctx->key_len, 113649a2135eSLin Jinhan ctx->iv, ctx->iv_len, in, out, len, enc); 113749a2135eSLin Jinhan default: 113849a2135eSLin Jinhan return -EINVAL; 113949a2135eSLin Jinhan } 114049a2135eSLin Jinhan } 1141d9332f1cSLin Jinhan 1142d9332f1cSLin Jinhan int rk_crypto_mac(struct udevice *dev, u32 algo, u32 mode, 1143d9332f1cSLin Jinhan const u8 *key, u32 key_len, 1144d9332f1cSLin Jinhan const u8 *in, u32 len, u8 *tag) 1145d9332f1cSLin Jinhan { 1146d9332f1cSLin Jinhan u32 rk_mode = RK_GET_RK_MODE(mode); 1147d9332f1cSLin Jinhan int ret; 1148d9332f1cSLin Jinhan 1149d9332f1cSLin Jinhan if (!IS_MAC_MODE(rk_mode)) 1150d9332f1cSLin Jinhan return -EINVAL; 1151d9332f1cSLin Jinhan 1152d9332f1cSLin Jinhan if (algo != CRYPTO_AES && algo != CRYPTO_SM4) 1153d9332f1cSLin Jinhan return -EINVAL; 1154d9332f1cSLin Jinhan 1155d9332f1cSLin Jinhan /* RV1126/RV1109 do not support aes-192 */ 1156d9332f1cSLin Jinhan #if defined(CONFIG_ROCKCHIP_RV1126) 1157d9332f1cSLin Jinhan if (algo == CRYPTO_AES && key_len == AES_KEYSIZE_192) 1158d9332f1cSLin Jinhan return -EINVAL; 1159d9332f1cSLin Jinhan #endif 1160d9332f1cSLin Jinhan 1161d9332f1cSLin Jinhan ret = hw_cipher_init(g_key_chn, key, NULL, key_len, NULL, 0, 1162d9332f1cSLin Jinhan algo, mode, true); 1163d9332f1cSLin Jinhan if (ret) 1164d9332f1cSLin Jinhan return ret; 1165d9332f1cSLin Jinhan 1166d9332f1cSLin Jinhan return hw_cipher_crypt(in, NULL, len, NULL, 0, 1167d9332f1cSLin Jinhan tag, AES_BLOCK_SIZE, mode); 1168d9332f1cSLin Jinhan } 1169d9332f1cSLin Jinhan 1170d9332f1cSLin Jinhan int rockchip_crypto_mac(struct udevice *dev, cipher_context *ctx, 1171d9332f1cSLin Jinhan const u8 *in, u32 len, u8 *tag) 1172d9332f1cSLin Jinhan { 1173d9332f1cSLin Jinhan return rk_crypto_mac(dev, ctx->algo, ctx->mode, 1174d9332f1cSLin Jinhan ctx->key, ctx->key_len, in, len, tag); 1175d9332f1cSLin Jinhan } 1176d9332f1cSLin Jinhan 1177*c3ce9937SLin Jinhan int rk_crypto_ae(struct udevice *dev, u32 algo, u32 mode, 1178*c3ce9937SLin Jinhan const u8 *key, u32 key_len, const u8 *nonce, u32 nonce_len, 1179*c3ce9937SLin Jinhan const u8 *in, u32 len, const u8 *aad, u32 aad_len, 1180*c3ce9937SLin Jinhan u8 *out, u8 *tag) 1181*c3ce9937SLin Jinhan { 1182*c3ce9937SLin Jinhan u32 rk_mode = RK_GET_RK_MODE(mode); 1183*c3ce9937SLin Jinhan int ret; 1184*c3ce9937SLin Jinhan 1185*c3ce9937SLin Jinhan if (!IS_AE_MODE(rk_mode)) 1186*c3ce9937SLin Jinhan return -EINVAL; 1187*c3ce9937SLin Jinhan 1188*c3ce9937SLin Jinhan if (algo != CRYPTO_AES && algo != CRYPTO_SM4) 1189*c3ce9937SLin Jinhan return -EINVAL; 1190*c3ce9937SLin Jinhan 1191*c3ce9937SLin Jinhan /* RV1126/RV1109 do not support aes-192 */ 1192*c3ce9937SLin Jinhan #if defined(CONFIG_ROCKCHIP_RV1126) 1193*c3ce9937SLin Jinhan if (algo == CRYPTO_AES && key_len == AES_KEYSIZE_192) 1194*c3ce9937SLin Jinhan return -EINVAL; 1195*c3ce9937SLin Jinhan #endif 1196*c3ce9937SLin Jinhan 1197*c3ce9937SLin Jinhan ret = hw_cipher_init(g_key_chn, key, NULL, key_len, nonce, nonce_len, 1198*c3ce9937SLin Jinhan algo, mode, true); 1199*c3ce9937SLin Jinhan if (ret) 1200*c3ce9937SLin Jinhan return ret; 1201*c3ce9937SLin Jinhan 1202*c3ce9937SLin Jinhan return hw_cipher_crypt(in, out, len, aad, aad_len, 1203*c3ce9937SLin Jinhan tag, AES_BLOCK_SIZE, mode); 1204*c3ce9937SLin Jinhan } 1205*c3ce9937SLin Jinhan 1206*c3ce9937SLin Jinhan int rockchip_crypto_ae(struct udevice *dev, cipher_context *ctx, 1207*c3ce9937SLin Jinhan const u8 *in, u32 len, const u8 *aad, u32 aad_len, 1208*c3ce9937SLin Jinhan u8 *out, u8 *tag) 1209*c3ce9937SLin Jinhan 1210*c3ce9937SLin Jinhan { 1211*c3ce9937SLin Jinhan return rk_crypto_ae(dev, ctx->algo, ctx->mode, ctx->key, ctx->key_len, 1212*c3ce9937SLin Jinhan ctx->iv, ctx->iv_len, in, len, 1213*c3ce9937SLin Jinhan aad, aad_len, out, tag); 1214*c3ce9937SLin Jinhan } 1215*c3ce9937SLin Jinhan 121649a2135eSLin Jinhan #endif 121749a2135eSLin Jinhan 1218864e581cSLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_RSA) 1219b353a43cSLin Jinhan static int rockchip_crypto_rsa_verify(struct udevice *dev, rsa_key *ctx, 1220b353a43cSLin Jinhan u8 *sign, u8 *output) 1221b353a43cSLin Jinhan { 1222b353a43cSLin Jinhan struct mpa_num *mpa_m = NULL, *mpa_e = NULL, *mpa_n = NULL; 1223b353a43cSLin Jinhan struct mpa_num *mpa_c = NULL, *mpa_result = NULL; 1224b353a43cSLin Jinhan u32 n_bits, n_words; 1225b353a43cSLin Jinhan u32 *rsa_result; 1226b353a43cSLin Jinhan int ret; 1227b353a43cSLin Jinhan 1228b353a43cSLin Jinhan if (!ctx) 1229b353a43cSLin Jinhan return -EINVAL; 1230b353a43cSLin Jinhan 1231b353a43cSLin Jinhan if (ctx->algo != CRYPTO_RSA512 && 1232b353a43cSLin Jinhan ctx->algo != CRYPTO_RSA1024 && 1233b353a43cSLin Jinhan ctx->algo != CRYPTO_RSA2048 && 1234b353a43cSLin Jinhan ctx->algo != CRYPTO_RSA3072 && 1235b353a43cSLin Jinhan ctx->algo != CRYPTO_RSA4096) 1236b353a43cSLin Jinhan return -EINVAL; 1237b353a43cSLin Jinhan 1238b353a43cSLin Jinhan n_bits = crypto_algo_nbits(ctx->algo); 1239b353a43cSLin Jinhan n_words = BITS2WORD(n_bits); 1240b353a43cSLin Jinhan 1241b353a43cSLin Jinhan rsa_result = malloc(BITS2BYTE(n_bits)); 1242b353a43cSLin Jinhan if (!rsa_result) 1243b353a43cSLin Jinhan return -ENOMEM; 1244b353a43cSLin Jinhan 1245b353a43cSLin Jinhan memset(rsa_result, 0x00, BITS2BYTE(n_bits)); 1246b353a43cSLin Jinhan 1247b353a43cSLin Jinhan ret = rk_mpa_alloc(&mpa_m); 1248b353a43cSLin Jinhan ret |= rk_mpa_alloc(&mpa_e); 1249b353a43cSLin Jinhan ret |= rk_mpa_alloc(&mpa_n); 1250b353a43cSLin Jinhan ret |= rk_mpa_alloc(&mpa_c); 1251b353a43cSLin Jinhan ret |= rk_mpa_alloc(&mpa_result); 1252b353a43cSLin Jinhan if (ret) 1253b353a43cSLin Jinhan goto exit; 1254b353a43cSLin Jinhan 1255b353a43cSLin Jinhan mpa_m->d = (void *)sign; 1256b353a43cSLin Jinhan mpa_e->d = (void *)ctx->e; 1257b353a43cSLin Jinhan mpa_n->d = (void *)ctx->n; 1258b353a43cSLin Jinhan mpa_c->d = (void *)ctx->c; 1259b353a43cSLin Jinhan mpa_result->d = (void *)rsa_result; 1260b353a43cSLin Jinhan 1261b353a43cSLin Jinhan mpa_m->size = n_words; 1262b353a43cSLin Jinhan mpa_e->size = n_words; 1263b353a43cSLin Jinhan mpa_n->size = n_words; 1264b353a43cSLin Jinhan mpa_c->size = n_words; 1265b353a43cSLin Jinhan mpa_result->size = n_words; 1266b353a43cSLin Jinhan 1267b353a43cSLin Jinhan ret = rk_exptmod_np(mpa_m, mpa_e, mpa_n, mpa_c, mpa_result); 1268b353a43cSLin Jinhan if (!ret) 1269b353a43cSLin Jinhan memcpy(output, rsa_result, BITS2BYTE(n_bits)); 1270b353a43cSLin Jinhan 1271b353a43cSLin Jinhan exit: 1272b353a43cSLin Jinhan free(rsa_result); 1273b353a43cSLin Jinhan rk_mpa_free(&mpa_m); 1274b353a43cSLin Jinhan rk_mpa_free(&mpa_e); 1275b353a43cSLin Jinhan rk_mpa_free(&mpa_n); 1276b353a43cSLin Jinhan rk_mpa_free(&mpa_c); 1277b353a43cSLin Jinhan rk_mpa_free(&mpa_result); 1278b353a43cSLin Jinhan 1279b353a43cSLin Jinhan return ret; 1280b353a43cSLin Jinhan } 1281864e581cSLin Jinhan #endif 1282b353a43cSLin Jinhan 1283b353a43cSLin Jinhan static const struct dm_crypto_ops rockchip_crypto_ops = { 1284b353a43cSLin Jinhan .capability = rockchip_crypto_capability, 1285b353a43cSLin Jinhan .sha_init = rockchip_crypto_sha_init, 1286b353a43cSLin Jinhan .sha_update = rockchip_crypto_sha_update, 1287b353a43cSLin Jinhan .sha_final = rockchip_crypto_sha_final, 128849a2135eSLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_RSA) 1289b353a43cSLin Jinhan .rsa_verify = rockchip_crypto_rsa_verify, 129049a2135eSLin Jinhan #endif 129149a2135eSLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_HMAC) 129249a2135eSLin Jinhan .hmac_init = rockchip_crypto_hmac_init, 129349a2135eSLin Jinhan .hmac_update = rockchip_crypto_hmac_update, 129449a2135eSLin Jinhan .hmac_final = rockchip_crypto_hmac_final, 129549a2135eSLin Jinhan #endif 129649a2135eSLin Jinhan #if CONFIG_IS_ENABLED(ROCKCHIP_CIPHER) 129749a2135eSLin Jinhan .cipher_crypt = rockchip_crypto_cipher, 1298d9332f1cSLin Jinhan .cipher_mac = rockchip_crypto_mac, 1299*c3ce9937SLin Jinhan .cipher_ae = rockchip_crypto_ae, 130049a2135eSLin Jinhan #endif 1301b353a43cSLin Jinhan }; 1302b353a43cSLin Jinhan 1303b353a43cSLin Jinhan /* 1304b353a43cSLin Jinhan * Only use "clocks" to parse crypto clock id and use rockchip_get_clk(). 1305b353a43cSLin Jinhan * Because we always add crypto node in U-Boot dts, when kernel dtb enabled : 1306b353a43cSLin Jinhan * 1307b353a43cSLin Jinhan * 1. There is cru phandle mismatch between U-Boot and kernel dtb; 1308b353a43cSLin Jinhan * 2. CONFIG_OF_SPL_REMOVE_PROPS removes clock property; 1309b353a43cSLin Jinhan */ 1310b353a43cSLin Jinhan static int rockchip_crypto_ofdata_to_platdata(struct udevice *dev) 1311b353a43cSLin Jinhan { 1312b353a43cSLin Jinhan struct rockchip_crypto_priv *priv = dev_get_priv(dev); 1313b353a43cSLin Jinhan int len, ret = -EINVAL; 1314b353a43cSLin Jinhan 1315b353a43cSLin Jinhan if (!dev_read_prop(dev, "clocks", &len)) { 1316b353a43cSLin Jinhan printf("Can't find \"clocks\" property\n"); 1317b353a43cSLin Jinhan return -EINVAL; 1318b353a43cSLin Jinhan } 1319b353a43cSLin Jinhan 1320b353a43cSLin Jinhan memset(priv, 0x00, sizeof(*priv)); 1321b353a43cSLin Jinhan priv->clocks = malloc(len); 1322b353a43cSLin Jinhan if (!priv->clocks) 1323b353a43cSLin Jinhan return -ENOMEM; 1324b353a43cSLin Jinhan 1325b353a43cSLin Jinhan priv->nclocks = len / sizeof(u32); 1326b353a43cSLin Jinhan if (dev_read_u32_array(dev, "clocks", (u32 *)priv->clocks, 1327b353a43cSLin Jinhan priv->nclocks)) { 1328b353a43cSLin Jinhan printf("Can't read \"clocks\" property\n"); 1329b353a43cSLin Jinhan ret = -EINVAL; 1330b353a43cSLin Jinhan goto exit; 1331b353a43cSLin Jinhan } 1332b353a43cSLin Jinhan 1333b353a43cSLin Jinhan if (!dev_read_prop(dev, "clock-frequency", &len)) { 1334b353a43cSLin Jinhan printf("Can't find \"clock-frequency\" property\n"); 1335b353a43cSLin Jinhan ret = -EINVAL; 1336b353a43cSLin Jinhan goto exit; 1337b353a43cSLin Jinhan } 1338b353a43cSLin Jinhan 1339b353a43cSLin Jinhan priv->frequencies = malloc(len); 1340b353a43cSLin Jinhan if (!priv->frequencies) { 1341b353a43cSLin Jinhan ret = -ENOMEM; 1342b353a43cSLin Jinhan goto exit; 1343b353a43cSLin Jinhan } 1344b353a43cSLin Jinhan 1345b353a43cSLin Jinhan priv->nclocks = len / sizeof(u32); 1346b353a43cSLin Jinhan if (dev_read_u32_array(dev, "clock-frequency", priv->frequencies, 1347b353a43cSLin Jinhan priv->nclocks)) { 1348b353a43cSLin Jinhan printf("Can't read \"clock-frequency\" property\n"); 1349b353a43cSLin Jinhan ret = -EINVAL; 1350b353a43cSLin Jinhan goto exit; 1351b353a43cSLin Jinhan } 1352b353a43cSLin Jinhan 1353b353a43cSLin Jinhan priv->reg = (fdt_addr_t)dev_read_addr_ptr(dev); 1354b353a43cSLin Jinhan 1355b353a43cSLin Jinhan crypto_base = priv->reg; 1356b353a43cSLin Jinhan 1357b353a43cSLin Jinhan return 0; 1358b353a43cSLin Jinhan exit: 1359b353a43cSLin Jinhan if (priv->clocks) 1360b353a43cSLin Jinhan free(priv->clocks); 1361b353a43cSLin Jinhan 1362b353a43cSLin Jinhan if (priv->frequencies) 1363b353a43cSLin Jinhan free(priv->frequencies); 1364b353a43cSLin Jinhan 1365b353a43cSLin Jinhan return ret; 1366b353a43cSLin Jinhan } 1367b353a43cSLin Jinhan 1368b353a43cSLin Jinhan static int rockchip_crypto_probe(struct udevice *dev) 1369b353a43cSLin Jinhan { 1370b353a43cSLin Jinhan struct rockchip_crypto_priv *priv = dev_get_priv(dev); 137149a2135eSLin Jinhan struct rk_crypto_soc_data *sdata; 1372b353a43cSLin Jinhan int i, ret = 0; 1373b353a43cSLin Jinhan u32* clocks; 1374b353a43cSLin Jinhan 137549a2135eSLin Jinhan sdata = (struct rk_crypto_soc_data *)dev_get_driver_data(dev); 137649a2135eSLin Jinhan priv->soc_data = sdata; 137749a2135eSLin Jinhan 137849a2135eSLin Jinhan priv->hw_ctx = memalign(LLI_ADDR_ALIGN_SIZE, 13791606a214SLin Jinhan sizeof(struct rk_hash_ctx)); 13801606a214SLin Jinhan if (!priv->hw_ctx) 13811606a214SLin Jinhan return -ENOMEM; 13821606a214SLin Jinhan 1383b353a43cSLin Jinhan ret = rockchip_get_clk(&priv->clk.dev); 1384b353a43cSLin Jinhan if (ret) { 1385b353a43cSLin Jinhan printf("Failed to get clk device, ret=%d\n", ret); 1386b353a43cSLin Jinhan return ret; 1387b353a43cSLin Jinhan } 1388b353a43cSLin Jinhan 1389b353a43cSLin Jinhan clocks = (u32 *)priv->clocks; 1390b353a43cSLin Jinhan for (i = 0; i < priv->nclocks; i++) { 1391b353a43cSLin Jinhan priv->clk.id = clocks[i * 2 + 1]; 1392b353a43cSLin Jinhan ret = clk_set_rate(&priv->clk, priv->frequencies[i]); 1393b353a43cSLin Jinhan if (ret < 0) { 1394b353a43cSLin Jinhan printf("%s: Failed to set clk(%ld): ret=%d\n", 1395b353a43cSLin Jinhan __func__, priv->clk.id, ret); 1396b353a43cSLin Jinhan return ret; 1397b353a43cSLin Jinhan } 1398b353a43cSLin Jinhan } 1399b353a43cSLin Jinhan 1400b353a43cSLin Jinhan hw_crypto_reset(); 1401b353a43cSLin Jinhan 1402b353a43cSLin Jinhan return 0; 1403b353a43cSLin Jinhan } 1404b353a43cSLin Jinhan 140549a2135eSLin Jinhan static const struct rk_crypto_soc_data soc_data_base = { 140649a2135eSLin Jinhan .capability = CRYPTO_MD5 | 140749a2135eSLin Jinhan CRYPTO_SHA1 | 140849a2135eSLin Jinhan CRYPTO_SHA256 | 140949a2135eSLin Jinhan CRYPTO_SHA512 | 141049a2135eSLin Jinhan CRYPTO_HMAC_MD5 | 141149a2135eSLin Jinhan CRYPTO_HMAC_SHA1 | 141249a2135eSLin Jinhan CRYPTO_HMAC_SHA256 | 141349a2135eSLin Jinhan CRYPTO_HMAC_SHA512 | 141449a2135eSLin Jinhan CRYPTO_RSA512 | 141549a2135eSLin Jinhan CRYPTO_RSA1024 | 141649a2135eSLin Jinhan CRYPTO_RSA2048 | 141749a2135eSLin Jinhan CRYPTO_RSA3072 | 141849a2135eSLin Jinhan CRYPTO_RSA4096 | 141949a2135eSLin Jinhan CRYPTO_DES | 142049a2135eSLin Jinhan CRYPTO_AES, 142149a2135eSLin Jinhan }; 142249a2135eSLin Jinhan 142349a2135eSLin Jinhan static const struct rk_crypto_soc_data soc_data_base_sm = { 142449a2135eSLin Jinhan .capability = CRYPTO_MD5 | 142549a2135eSLin Jinhan CRYPTO_SHA1 | 142649a2135eSLin Jinhan CRYPTO_SHA256 | 142749a2135eSLin Jinhan CRYPTO_SHA512 | 142849a2135eSLin Jinhan CRYPTO_SM3 | 142949a2135eSLin Jinhan CRYPTO_HMAC_MD5 | 143049a2135eSLin Jinhan CRYPTO_HMAC_SHA1 | 143149a2135eSLin Jinhan CRYPTO_HMAC_SHA256 | 143249a2135eSLin Jinhan CRYPTO_HMAC_SHA512 | 143349a2135eSLin Jinhan CRYPTO_HMAC_SM3 | 143449a2135eSLin Jinhan CRYPTO_RSA512 | 143549a2135eSLin Jinhan CRYPTO_RSA1024 | 143649a2135eSLin Jinhan CRYPTO_RSA2048 | 143749a2135eSLin Jinhan CRYPTO_RSA3072 | 143849a2135eSLin Jinhan CRYPTO_RSA4096 | 143949a2135eSLin Jinhan CRYPTO_DES | 144049a2135eSLin Jinhan CRYPTO_AES | 144149a2135eSLin Jinhan CRYPTO_SM4, 144249a2135eSLin Jinhan }; 144349a2135eSLin Jinhan 144449a2135eSLin Jinhan static const struct rk_crypto_soc_data soc_data_rk1808 = { 144549a2135eSLin Jinhan .capability = CRYPTO_MD5 | 144649a2135eSLin Jinhan CRYPTO_SHA1 | 144749a2135eSLin Jinhan CRYPTO_SHA256 | 144849a2135eSLin Jinhan CRYPTO_HMAC_MD5 | 144949a2135eSLin Jinhan CRYPTO_HMAC_SHA1 | 145049a2135eSLin Jinhan CRYPTO_HMAC_SHA256 | 145149a2135eSLin Jinhan CRYPTO_RSA512 | 145249a2135eSLin Jinhan CRYPTO_RSA1024 | 145349a2135eSLin Jinhan CRYPTO_RSA2048 | 145449a2135eSLin Jinhan CRYPTO_RSA3072 | 145549a2135eSLin Jinhan CRYPTO_RSA4096, 145649a2135eSLin Jinhan }; 145749a2135eSLin Jinhan 1458b353a43cSLin Jinhan static const struct udevice_id rockchip_crypto_ids[] = { 145949a2135eSLin Jinhan { 146049a2135eSLin Jinhan .compatible = "rockchip,px30-crypto", 146149a2135eSLin Jinhan .data = (ulong)&soc_data_base 146249a2135eSLin Jinhan }, 146349a2135eSLin Jinhan { 146449a2135eSLin Jinhan .compatible = "rockchip,rk1808-crypto", 146549a2135eSLin Jinhan .data = (ulong)&soc_data_rk1808 146649a2135eSLin Jinhan }, 146749a2135eSLin Jinhan { 146849a2135eSLin Jinhan .compatible = "rockchip,rk3308-crypto", 146949a2135eSLin Jinhan .data = (ulong)&soc_data_base 147049a2135eSLin Jinhan }, 147149a2135eSLin Jinhan { 147249a2135eSLin Jinhan .compatible = "rockchip,rv1126-crypto", 147349a2135eSLin Jinhan .data = (ulong)&soc_data_base_sm 147449a2135eSLin Jinhan }, 147549a2135eSLin Jinhan { 147649a2135eSLin Jinhan .compatible = "rockchip,rk3568-crypto", 147749a2135eSLin Jinhan .data = (ulong)&soc_data_base_sm 147849a2135eSLin Jinhan }, 1479b353a43cSLin Jinhan { } 1480b353a43cSLin Jinhan }; 1481b353a43cSLin Jinhan 1482b353a43cSLin Jinhan U_BOOT_DRIVER(rockchip_crypto_v2) = { 1483b353a43cSLin Jinhan .name = "rockchip_crypto_v2", 1484b353a43cSLin Jinhan .id = UCLASS_CRYPTO, 1485b353a43cSLin Jinhan .of_match = rockchip_crypto_ids, 1486b353a43cSLin Jinhan .ops = &rockchip_crypto_ops, 1487b353a43cSLin Jinhan .probe = rockchip_crypto_probe, 1488b353a43cSLin Jinhan .ofdata_to_platdata = rockchip_crypto_ofdata_to_platdata, 1489b353a43cSLin Jinhan .priv_auto_alloc_size = sizeof(struct rockchip_crypto_priv), 1490b353a43cSLin Jinhan }; 1491