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