1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd 4 */ 5 6 #include <common.h> 7 #include <clk.h> 8 #include <crypto.h> 9 #include <dm.h> 10 #include <reset.h> 11 #include <rockchip/crypto_hash_cache.h> 12 #include <rockchip/crypto_v1.h> 13 #include <asm/io.h> 14 #include <asm/arch/hardware.h> 15 #include <asm/arch/clock.h> 16 17 #define CRYPTO_V1_DEFAULT_RATE 100000000 18 /* crypto timeout 500ms, must support more than 32M data per times*/ 19 #define HASH_UPDATE_LIMIT (32 * 1024 * 1024) 20 #define RK_CRYPTO_TIME_OUT 500000 21 22 #define LLI_ADDR_ALIGN_SIZE 8 23 #define DATA_ADDR_ALIGN_SIZE 8 24 #define DATA_LEN_ALIGN_SIZE 64 25 26 struct rockchip_crypto_priv { 27 struct crypto_hash_cache *hash_cache; 28 struct rk_crypto_reg *reg; 29 struct clk clk; 30 struct reset_ctl_bulk rsts; 31 sha_context *ctx; 32 u32 frequency; 33 char *clocks; 34 u32 nclocks; 35 u32 length; 36 }; 37 38 static u32 rockchip_crypto_capability(struct udevice *dev) 39 { 40 return CRYPTO_MD5 | 41 CRYPTO_SHA1 | 42 CRYPTO_SHA256 | 43 CRYPTO_RSA512 | 44 CRYPTO_RSA1024 | 45 CRYPTO_RSA2048; 46 } 47 48 static int rk_hash_direct_calc(void *hw_data, const u8 *data, 49 u32 data_len, u8 *started_flag, u8 is_last) 50 { 51 struct rockchip_crypto_priv *priv = hw_data; 52 struct rk_crypto_reg *reg = priv->reg; 53 54 if (!data_len) 55 return -EINVAL; 56 57 /* Must flush dcache before crypto DMA fetch data region */ 58 crypto_flush_cacheline((ulong)data, data_len); 59 60 /* Hash Done Interrupt */ 61 writel(HASH_DONE_INT, ®->crypto_intsts); 62 63 /* Set data base and length */ 64 writel((u32)(ulong)data, ®->crypto_hrdmas); 65 writel((data_len + 3) >> 2, ®->crypto_hrdmal); 66 67 /* Write 1 to start. When finishes, the core will clear it */ 68 rk_setreg(®->crypto_ctrl, HASH_START); 69 70 /* Wait last complete */ 71 do {} while (readl(®->crypto_ctrl) & HASH_START); 72 73 priv->length += data_len; 74 75 return 0; 76 } 77 78 static int rockchip_crypto_sha_init(struct udevice *dev, sha_context *ctx) 79 { 80 struct rockchip_crypto_priv *priv = dev_get_priv(dev); 81 struct rk_crypto_reg *reg = priv->reg; 82 u32 val; 83 84 if (!ctx) 85 return -EINVAL; 86 87 if (!ctx->length) { 88 printf("Crypto-v1: require data total length for sha init\n"); 89 return -EINVAL; 90 } 91 92 priv->hash_cache = crypto_hash_cache_alloc(rk_hash_direct_calc, 93 priv, ctx->length, 94 DATA_ADDR_ALIGN_SIZE, 95 DATA_LEN_ALIGN_SIZE); 96 if (!priv->hash_cache) 97 return -EFAULT; 98 99 priv->ctx = ctx; 100 priv->length = 0; 101 writel(ctx->length, ®->crypto_hash_msg_len); 102 if (ctx->algo == CRYPTO_SHA256) { 103 /* Set SHA256 mode and out byte swap */ 104 writel(HASH_SWAP_DO | ENGINE_SELECTION_SHA256, 105 ®->crypto_hash_ctrl); 106 107 val = readl(®->crypto_conf); 108 val &= ~BYTESWAP_HRFIFO; 109 writel(val, ®->crypto_conf); 110 } else if (ctx->algo == CRYPTO_SHA1) { 111 /* Set SHA160 input byte swap */ 112 val = readl(®->crypto_conf); 113 val |= BYTESWAP_HRFIFO; 114 writel(val, ®->crypto_conf); 115 116 /* Set SHA160 mode and out byte swap */ 117 writel(HASH_SWAP_DO, ®->crypto_hash_ctrl); 118 } else if (ctx->algo == CRYPTO_MD5) { 119 /* Set MD5 input byte swap */ 120 val = readl(®->crypto_conf); 121 val |= BYTESWAP_HRFIFO; 122 writel(val, ®->crypto_conf); 123 124 /* Set MD5 mode and out byte swap */ 125 writel(HASH_SWAP_DO | ENGINE_SELECTION_MD5, 126 ®->crypto_hash_ctrl); 127 } else { 128 return -EINVAL; 129 } 130 131 rk_setreg(®->crypto_ctrl, HASH_FLUSH); 132 do {} while (readl(®->crypto_ctrl) & HASH_FLUSH); 133 134 /* SHA256 needs input byte swap */ 135 if (ctx->algo == CRYPTO_SHA256) { 136 val = readl(®->crypto_conf); 137 val |= BYTESWAP_HRFIFO; 138 writel(val, ®->crypto_conf); 139 } 140 141 return 0; 142 } 143 144 static int rockchip_crypto_sha_update(struct udevice *dev, 145 u32 *input, u32 len) 146 { 147 struct rockchip_crypto_priv *priv = dev_get_priv(dev); 148 int ret = -EINVAL, i; 149 u8 *p; 150 151 if (!input || !len) 152 goto exit; 153 154 p = (u8 *)input; 155 156 for (i = 0; i < len / HASH_UPDATE_LIMIT; i++, p += HASH_UPDATE_LIMIT) { 157 ret = crypto_hash_update_with_cache(priv->hash_cache, p, 158 HASH_UPDATE_LIMIT); 159 if (ret) 160 goto exit; 161 } 162 163 if (len % HASH_UPDATE_LIMIT) 164 ret = crypto_hash_update_with_cache(priv->hash_cache, p, 165 len % HASH_UPDATE_LIMIT); 166 167 exit: 168 if (ret) { 169 crypto_hash_cache_free(priv->hash_cache); 170 priv->hash_cache = NULL; 171 } 172 173 return ret; 174 } 175 176 static int rockchip_crypto_sha_final(struct udevice *dev, 177 sha_context *ctx, u8 *output) 178 { 179 struct rockchip_crypto_priv *priv = dev_get_priv(dev); 180 struct rk_crypto_reg *reg = priv->reg; 181 u32 *buf = (u32 *)output; 182 int ret = 0; 183 u32 nbits; 184 int i; 185 186 if (priv->length != ctx->length) { 187 printf("total length(0x%08x) != init length(0x%08x)!\n", 188 priv->length, ctx->length); 189 ret = -EIO; 190 goto exit; 191 } 192 193 /* Wait last complete */ 194 do {} while (readl(®->crypto_ctrl) & HASH_START); 195 196 /* It is high when finish, and it will not be low until it restart */ 197 do {} while (!readl(®->crypto_hash_sts)); 198 199 /* Read hash data, per-data 32-bit */ 200 nbits = crypto_algo_nbits(ctx->algo); 201 for (i = 0; i < BITS2WORD(nbits); i++) 202 buf[i] = readl(®->crypto_hash_dout[i]); 203 204 exit: 205 crypto_hash_cache_free(priv->hash_cache); 206 priv->hash_cache = NULL; 207 return ret; 208 } 209 210 #if CONFIG_IS_ENABLED(ROCKCHIP_RSA) 211 static int rockchip_crypto_rsa_verify(struct udevice *dev, rsa_key *ctx, 212 u8 *sign, u8 *output) 213 { 214 struct rockchip_crypto_priv *priv = dev_get_priv(dev); 215 struct rk_crypto_reg *reg = priv->reg; 216 u32 nbits, *buf = (u32 *)output; 217 int i, value; 218 219 if (!ctx) 220 return -EINVAL; 221 222 if (ctx->algo == CRYPTO_RSA512) 223 value = PKA_BLOCK_SIZE_512; 224 else if (ctx->algo == CRYPTO_RSA1024) 225 value = PKA_BLOCK_SIZE_1024; 226 else if (ctx->algo == CRYPTO_RSA2048) 227 value = PKA_BLOCK_SIZE_2048; 228 else 229 return -EINVAL; 230 231 if (priv->rsts.resets && priv->rsts.count) { 232 reset_assert_bulk(&priv->rsts); 233 udelay(10); 234 reset_deassert_bulk(&priv->rsts); 235 } 236 237 /* Specify the nbits of N in PKA calculation */ 238 writel(value, ®->crypto_pka_ctrl); 239 240 /* Flush SHA and RSA */ 241 rk_setreg(®->crypto_ctrl, PKA_HASH_CTRL); 242 writel(0xffffffff, ®->crypto_intsts); 243 do {} while (readl(®->crypto_ctrl) & PKA_CTRL); 244 245 /* Clean PKA done interrupt */ 246 writel(PKA_DONE_INT, ®->crypto_intsts); 247 248 /* Set m/n/e/c */ 249 nbits = crypto_algo_nbits(ctx->algo); 250 memcpy((void *)®->crypto_pka_m, (void *)sign, BITS2BYTE(nbits)); 251 memcpy((void *)®->crypto_pka_n, (void *)ctx->n, BITS2BYTE(nbits)); 252 memcpy((void *)®->crypto_pka_e, (void *)ctx->e, BITS2BYTE(nbits)); 253 memcpy((void *)®->crypto_pka_c, (void *)ctx->c, BITS2BYTE(nbits)); 254 do {} while (readl(®->crypto_ctrl) & PKA_START); 255 256 /* Start PKA */ 257 rk_setreg(®->crypto_ctrl, PKA_START); 258 259 /* Wait PKA done */ 260 do {} while (readl(®->crypto_ctrl) & PKA_START); 261 262 /* Read hash data, per-data 32-bit */ 263 for (i = 0; i < BITS2WORD(nbits); i++) 264 buf[i] = readl(®->crypto_pka_m[i]); 265 266 return 0; 267 } 268 #else 269 static int rockchip_crypto_rsa_verify(struct udevice *dev, rsa_key *ctx, 270 u8 *sign, u8 *output) 271 { 272 return -ENOSYS; 273 } 274 #endif 275 static const struct dm_crypto_ops rockchip_crypto_ops = { 276 .capability = rockchip_crypto_capability, 277 .sha_init = rockchip_crypto_sha_init, 278 .sha_update = rockchip_crypto_sha_update, 279 .sha_final = rockchip_crypto_sha_final, 280 .rsa_verify = rockchip_crypto_rsa_verify, 281 }; 282 283 /* 284 * Only use "clocks" to parse crypto clock id and use rockchip_get_clk(). 285 * Because we always add crypto node in U-Boot dts, when kernel dtb enabled : 286 * 287 * 1. There is cru phandle mismatch between U-Boot and kernel dtb; 288 * 2. CONFIG_OF_SPL_REMOVE_PROPS removes clock property; 289 */ 290 static int rockchip_crypto_ofdata_to_platdata(struct udevice *dev) 291 { 292 struct rockchip_crypto_priv *priv = dev_get_priv(dev); 293 int len; 294 295 if (!dev_read_prop(dev, "clocks", &len)) { 296 printf("Crypto-v1: can't find \"clocks\" property\n"); 297 return -EINVAL; 298 } 299 300 priv->clocks = malloc(len); 301 if (!priv->clocks) 302 return -ENOMEM; 303 304 priv->nclocks = len / sizeof(u32); 305 if (dev_read_u32_array(dev, "clocks", (u32 *)priv->clocks, 306 priv->nclocks)) { 307 printf("Crypto-v1: can't read \"clocks\" property\n"); 308 return -EINVAL; 309 } 310 311 priv->reg = dev_read_addr_ptr(dev); 312 priv->frequency = dev_read_u32_default(dev, "clock-frequency", 313 CRYPTO_V1_DEFAULT_RATE); 314 315 memset(&priv->rsts, 0x00, sizeof(priv->rsts)); 316 reset_get_bulk(dev, &priv->rsts); 317 318 return 0; 319 } 320 321 static int rockchip_crypto_probe(struct udevice *dev) 322 { 323 struct rockchip_crypto_priv *priv = dev_get_priv(dev); 324 u32 *clocks; 325 int i, ret; 326 327 ret = rockchip_get_clk(&priv->clk.dev); 328 if (ret) { 329 printf("Crypto-v1: failed to get clk device, ret=%d\n", ret); 330 return ret; 331 } 332 333 clocks = (u32 *)priv->clocks; 334 for (i = 1; i < priv->nclocks; i += 2) { 335 priv->clk.id = clocks[i]; 336 ret = clk_set_rate(&priv->clk, priv->frequency); 337 if (ret < 0) { 338 printf("Crypto-v1: failed to set clk(%ld): ret=%d\n", 339 priv->clk.id, ret); 340 return ret; 341 } 342 } 343 344 return 0; 345 } 346 347 static const struct udevice_id rockchip_crypto_ids[] = { 348 { .compatible = "rockchip,rk3399-crypto" }, 349 { .compatible = "rockchip,rk3368-crypto" }, 350 { .compatible = "rockchip,rk3328-crypto" }, 351 { .compatible = "rockchip,rk3288-crypto" }, 352 { .compatible = "rockchip,rk322x-crypto" }, 353 { .compatible = "rockchip,rk312x-crypto" }, 354 { } 355 }; 356 357 U_BOOT_DRIVER(rockchip_crypto_v1) = { 358 .name = "rockchip_crypto_v1", 359 .id = UCLASS_CRYPTO, 360 .of_match = rockchip_crypto_ids, 361 .ops = &rockchip_crypto_ops, 362 .probe = rockchip_crypto_probe, 363 .ofdata_to_platdata = rockchip_crypto_ofdata_to_platdata, 364 .priv_auto_alloc_size = sizeof(struct rockchip_crypto_priv), 365 }; 366