1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * exynos-rng.c - Random Number Generator driver for the Exynos 4 * 5 * Copyright (c) 2017 Krzysztof Kozlowski <krzk@kernel.org> 6 * 7 * Loosely based on old driver from drivers/char/hw_random/exynos-rng.c: 8 * Copyright (C) 2012 Samsung Electronics 9 * Jonghwa Lee <jonghwa3.lee@samsung.com> 10 */ 11 12 #include <linux/clk.h> 13 #include <linux/crypto.h> 14 #include <linux/err.h> 15 #include <linux/io.h> 16 #include <linux/module.h> 17 #include <linux/mutex.h> 18 #include <linux/of.h> 19 #include <linux/platform_device.h> 20 21 #include <crypto/internal/rng.h> 22 23 #define EXYNOS_RNG_CONTROL 0x0 24 #define EXYNOS_RNG_STATUS 0x10 25 26 #define EXYNOS_RNG_SEED_CONF 0x14 27 #define EXYNOS_RNG_GEN_PRNG BIT(1) 28 29 #define EXYNOS_RNG_SEED_BASE 0x140 30 #define EXYNOS_RNG_SEED(n) (EXYNOS_RNG_SEED_BASE + (n * 0x4)) 31 #define EXYNOS_RNG_OUT_BASE 0x160 32 #define EXYNOS_RNG_OUT(n) (EXYNOS_RNG_OUT_BASE + (n * 0x4)) 33 34 /* EXYNOS_RNG_CONTROL bit fields */ 35 #define EXYNOS_RNG_CONTROL_START 0x18 36 /* EXYNOS_RNG_STATUS bit fields */ 37 #define EXYNOS_RNG_STATUS_SEED_SETTING_DONE BIT(1) 38 #define EXYNOS_RNG_STATUS_RNG_DONE BIT(5) 39 40 /* Five seed and output registers, each 4 bytes */ 41 #define EXYNOS_RNG_SEED_REGS 5 42 #define EXYNOS_RNG_SEED_SIZE (EXYNOS_RNG_SEED_REGS * 4) 43 44 enum exynos_prng_type { 45 EXYNOS_PRNG_UNKNOWN = 0, 46 EXYNOS_PRNG_EXYNOS4, 47 EXYNOS_PRNG_EXYNOS5, 48 }; 49 50 /* 51 * Driver re-seeds itself with generated random numbers to hinder 52 * backtracking of the original seed. 53 * 54 * Time for next re-seed in ms. 55 */ 56 #define EXYNOS_RNG_RESEED_TIME 1000 57 #define EXYNOS_RNG_RESEED_BYTES 65536 58 59 /* 60 * In polling mode, do not wait infinitely for the engine to finish the work. 61 */ 62 #define EXYNOS_RNG_WAIT_RETRIES 100 63 64 /* Context for crypto */ 65 struct exynos_rng_ctx { 66 struct exynos_rng_dev *rng; 67 }; 68 69 /* Device associated memory */ 70 struct exynos_rng_dev { 71 struct device *dev; 72 enum exynos_prng_type type; 73 void __iomem *mem; 74 struct clk *clk; 75 struct mutex lock; 76 /* Generated numbers stored for seeding during resume */ 77 u8 seed_save[EXYNOS_RNG_SEED_SIZE]; 78 unsigned int seed_save_len; 79 /* Time of last seeding in jiffies */ 80 unsigned long last_seeding; 81 /* Bytes generated since last seeding */ 82 unsigned long bytes_seeding; 83 }; 84 85 static struct exynos_rng_dev *exynos_rng_dev; 86 87 static u32 exynos_rng_readl(struct exynos_rng_dev *rng, u32 offset) 88 { 89 return readl_relaxed(rng->mem + offset); 90 } 91 92 static void exynos_rng_writel(struct exynos_rng_dev *rng, u32 val, u32 offset) 93 { 94 writel_relaxed(val, rng->mem + offset); 95 } 96 97 static int exynos_rng_set_seed(struct exynos_rng_dev *rng, 98 const u8 *seed, unsigned int slen) 99 { 100 u32 val; 101 int i; 102 103 /* Round seed length because loop iterates over full register size */ 104 slen = ALIGN_DOWN(slen, 4); 105 106 if (slen < EXYNOS_RNG_SEED_SIZE) 107 return -EINVAL; 108 109 for (i = 0; i < slen ; i += 4) { 110 unsigned int seed_reg = (i / 4) % EXYNOS_RNG_SEED_REGS; 111 112 val = seed[i] << 24; 113 val |= seed[i + 1] << 16; 114 val |= seed[i + 2] << 8; 115 val |= seed[i + 3] << 0; 116 117 exynos_rng_writel(rng, val, EXYNOS_RNG_SEED(seed_reg)); 118 } 119 120 val = exynos_rng_readl(rng, EXYNOS_RNG_STATUS); 121 if (!(val & EXYNOS_RNG_STATUS_SEED_SETTING_DONE)) { 122 dev_warn(rng->dev, "Seed setting not finished\n"); 123 return -EIO; 124 } 125 126 rng->last_seeding = jiffies; 127 rng->bytes_seeding = 0; 128 129 return 0; 130 } 131 132 /* 133 * Start the engine and poll for finish. Then read from output registers 134 * filling the 'dst' buffer up to 'dlen' bytes or up to size of generated 135 * random data (EXYNOS_RNG_SEED_SIZE). 136 * 137 * On success: return 0 and store number of read bytes under 'read' address. 138 * On error: return -ERRNO. 139 */ 140 static int exynos_rng_get_random(struct exynos_rng_dev *rng, 141 u8 *dst, unsigned int dlen, 142 unsigned int *read) 143 { 144 int retry = EXYNOS_RNG_WAIT_RETRIES; 145 146 if (rng->type == EXYNOS_PRNG_EXYNOS4) { 147 exynos_rng_writel(rng, EXYNOS_RNG_CONTROL_START, 148 EXYNOS_RNG_CONTROL); 149 } else if (rng->type == EXYNOS_PRNG_EXYNOS5) { 150 exynos_rng_writel(rng, EXYNOS_RNG_GEN_PRNG, 151 EXYNOS_RNG_SEED_CONF); 152 } 153 154 while (!(exynos_rng_readl(rng, 155 EXYNOS_RNG_STATUS) & EXYNOS_RNG_STATUS_RNG_DONE) && --retry) 156 cpu_relax(); 157 158 if (!retry) 159 return -ETIMEDOUT; 160 161 /* Clear status bit */ 162 exynos_rng_writel(rng, EXYNOS_RNG_STATUS_RNG_DONE, 163 EXYNOS_RNG_STATUS); 164 *read = min_t(size_t, dlen, EXYNOS_RNG_SEED_SIZE); 165 memcpy_fromio(dst, rng->mem + EXYNOS_RNG_OUT_BASE, *read); 166 rng->bytes_seeding += *read; 167 168 return 0; 169 } 170 171 /* Re-seed itself from time to time */ 172 static void exynos_rng_reseed(struct exynos_rng_dev *rng) 173 { 174 unsigned long next_seeding = rng->last_seeding + \ 175 msecs_to_jiffies(EXYNOS_RNG_RESEED_TIME); 176 unsigned long now = jiffies; 177 unsigned int read = 0; 178 u8 seed[EXYNOS_RNG_SEED_SIZE]; 179 180 if (time_before(now, next_seeding) && 181 rng->bytes_seeding < EXYNOS_RNG_RESEED_BYTES) 182 return; 183 184 if (exynos_rng_get_random(rng, seed, sizeof(seed), &read)) 185 return; 186 187 exynos_rng_set_seed(rng, seed, read); 188 189 /* Let others do some of their job. */ 190 mutex_unlock(&rng->lock); 191 mutex_lock(&rng->lock); 192 } 193 194 static int exynos_rng_generate(struct crypto_rng *tfm, 195 const u8 *src, unsigned int slen, 196 u8 *dst, unsigned int dlen) 197 { 198 struct exynos_rng_ctx *ctx = crypto_rng_ctx(tfm); 199 struct exynos_rng_dev *rng = ctx->rng; 200 unsigned int read = 0; 201 int ret; 202 203 ret = clk_prepare_enable(rng->clk); 204 if (ret) 205 return ret; 206 207 mutex_lock(&rng->lock); 208 do { 209 ret = exynos_rng_get_random(rng, dst, dlen, &read); 210 if (ret) 211 break; 212 213 dlen -= read; 214 dst += read; 215 216 exynos_rng_reseed(rng); 217 } while (dlen > 0); 218 mutex_unlock(&rng->lock); 219 220 clk_disable_unprepare(rng->clk); 221 222 return ret; 223 } 224 225 static int exynos_rng_seed(struct crypto_rng *tfm, const u8 *seed, 226 unsigned int slen) 227 { 228 struct exynos_rng_ctx *ctx = crypto_rng_ctx(tfm); 229 struct exynos_rng_dev *rng = ctx->rng; 230 int ret; 231 232 ret = clk_prepare_enable(rng->clk); 233 if (ret) 234 return ret; 235 236 mutex_lock(&rng->lock); 237 ret = exynos_rng_set_seed(ctx->rng, seed, slen); 238 mutex_unlock(&rng->lock); 239 240 clk_disable_unprepare(rng->clk); 241 242 return ret; 243 } 244 245 static int exynos_rng_kcapi_init(struct crypto_tfm *tfm) 246 { 247 struct exynos_rng_ctx *ctx = crypto_tfm_ctx(tfm); 248 249 ctx->rng = exynos_rng_dev; 250 251 return 0; 252 } 253 254 static struct rng_alg exynos_rng_alg = { 255 .generate = exynos_rng_generate, 256 .seed = exynos_rng_seed, 257 .seedsize = EXYNOS_RNG_SEED_SIZE, 258 .base = { 259 .cra_name = "stdrng", 260 .cra_driver_name = "exynos_rng", 261 .cra_priority = 300, 262 .cra_ctxsize = sizeof(struct exynos_rng_ctx), 263 .cra_module = THIS_MODULE, 264 .cra_init = exynos_rng_kcapi_init, 265 } 266 }; 267 268 static int exynos_rng_probe(struct platform_device *pdev) 269 { 270 struct exynos_rng_dev *rng; 271 int ret; 272 273 if (exynos_rng_dev) 274 return -EEXIST; 275 276 rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL); 277 if (!rng) 278 return -ENOMEM; 279 280 rng->type = (uintptr_t)of_device_get_match_data(&pdev->dev); 281 282 mutex_init(&rng->lock); 283 284 rng->dev = &pdev->dev; 285 rng->clk = devm_clk_get(&pdev->dev, "secss"); 286 if (IS_ERR(rng->clk)) { 287 dev_err(&pdev->dev, "Couldn't get clock.\n"); 288 return PTR_ERR(rng->clk); 289 } 290 291 rng->mem = devm_platform_ioremap_resource(pdev, 0); 292 if (IS_ERR(rng->mem)) 293 return PTR_ERR(rng->mem); 294 295 platform_set_drvdata(pdev, rng); 296 297 exynos_rng_dev = rng; 298 299 ret = crypto_register_rng(&exynos_rng_alg); 300 if (ret) { 301 dev_err(&pdev->dev, 302 "Couldn't register rng crypto alg: %d\n", ret); 303 exynos_rng_dev = NULL; 304 } 305 306 return ret; 307 } 308 309 static void exynos_rng_remove(struct platform_device *pdev) 310 { 311 crypto_unregister_rng(&exynos_rng_alg); 312 313 exynos_rng_dev = NULL; 314 } 315 316 static int __maybe_unused exynos_rng_suspend(struct device *dev) 317 { 318 struct exynos_rng_dev *rng = dev_get_drvdata(dev); 319 int ret; 320 321 /* If we were never seeded then after resume it will be the same */ 322 if (!rng->last_seeding) 323 return 0; 324 325 rng->seed_save_len = 0; 326 ret = clk_prepare_enable(rng->clk); 327 if (ret) 328 return ret; 329 330 mutex_lock(&rng->lock); 331 332 /* Get new random numbers and store them for seeding on resume. */ 333 exynos_rng_get_random(rng, rng->seed_save, sizeof(rng->seed_save), 334 &(rng->seed_save_len)); 335 336 mutex_unlock(&rng->lock); 337 338 dev_dbg(rng->dev, "Stored %u bytes for seeding on system resume\n", 339 rng->seed_save_len); 340 341 clk_disable_unprepare(rng->clk); 342 343 return 0; 344 } 345 346 static int __maybe_unused exynos_rng_resume(struct device *dev) 347 { 348 struct exynos_rng_dev *rng = dev_get_drvdata(dev); 349 int ret; 350 351 /* Never seeded so nothing to do */ 352 if (!rng->last_seeding) 353 return 0; 354 355 ret = clk_prepare_enable(rng->clk); 356 if (ret) 357 return ret; 358 359 mutex_lock(&rng->lock); 360 361 ret = exynos_rng_set_seed(rng, rng->seed_save, rng->seed_save_len); 362 363 mutex_unlock(&rng->lock); 364 365 clk_disable_unprepare(rng->clk); 366 367 return ret; 368 } 369 370 static SIMPLE_DEV_PM_OPS(exynos_rng_pm_ops, exynos_rng_suspend, 371 exynos_rng_resume); 372 373 static const struct of_device_id exynos_rng_dt_match[] = { 374 { 375 .compatible = "samsung,exynos4-rng", 376 .data = (const void *)EXYNOS_PRNG_EXYNOS4, 377 }, { 378 .compatible = "samsung,exynos5250-prng", 379 .data = (const void *)EXYNOS_PRNG_EXYNOS5, 380 }, 381 { }, 382 }; 383 MODULE_DEVICE_TABLE(of, exynos_rng_dt_match); 384 385 static struct platform_driver exynos_rng_driver = { 386 .driver = { 387 .name = "exynos-rng", 388 .pm = &exynos_rng_pm_ops, 389 .of_match_table = exynos_rng_dt_match, 390 }, 391 .probe = exynos_rng_probe, 392 .remove = exynos_rng_remove, 393 }; 394 395 module_platform_driver(exynos_rng_driver); 396 397 MODULE_DESCRIPTION("Exynos H/W Random Number Generator driver"); 398 MODULE_AUTHOR("Krzysztof Kozlowski <krzk@kernel.org>"); 399 MODULE_LICENSE("GPL v2"); 400