1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * sun4i-ss-core.c - hardware cryptographic accelerator for Allwinner A20 SoC 4 * 5 * Copyright (C) 2013-2015 Corentin LABBE <clabbe.montjoie@gmail.com> 6 * 7 * Core file which registers crypto algorithms supported by the SS. 8 * 9 * You could find a link for the datasheet in Documentation/arch/arm/sunxi.rst 10 */ 11 #include <linux/clk.h> 12 #include <linux/crypto.h> 13 #include <linux/debugfs.h> 14 #include <linux/io.h> 15 #include <linux/module.h> 16 #include <linux/of.h> 17 #include <linux/platform_device.h> 18 #include <crypto/scatterwalk.h> 19 #include <linux/scatterlist.h> 20 #include <linux/interrupt.h> 21 #include <linux/delay.h> 22 #include <linux/reset.h> 23 24 #include "sun4i-ss.h" 25 26 static const struct ss_variant ss_a10_variant = { 27 .sha1_in_be = false, 28 }; 29 30 static const struct ss_variant ss_a33_variant = { 31 .sha1_in_be = true, 32 }; 33 34 static struct sun4i_ss_alg_template ss_algs[] = { 35 { .type = CRYPTO_ALG_TYPE_AHASH, 36 .mode = SS_OP_MD5, 37 .alg.hash = { 38 .init = sun4i_hash_init, 39 .update = sun4i_hash_update, 40 .final = sun4i_hash_final, 41 .finup = sun4i_hash_finup, 42 .digest = sun4i_hash_digest, 43 .export = sun4i_hash_export_md5, 44 .import = sun4i_hash_import_md5, 45 .halg = { 46 .digestsize = MD5_DIGEST_SIZE, 47 .statesize = sizeof(struct md5_state), 48 .base = { 49 .cra_name = "md5", 50 .cra_driver_name = "md5-sun4i-ss", 51 .cra_priority = 300, 52 .cra_alignmask = 3, 53 .cra_blocksize = MD5_HMAC_BLOCK_SIZE, 54 .cra_ctxsize = sizeof(struct sun4i_req_ctx), 55 .cra_module = THIS_MODULE, 56 .cra_init = sun4i_hash_crainit, 57 .cra_exit = sun4i_hash_craexit, 58 } 59 } 60 } 61 }, 62 { .type = CRYPTO_ALG_TYPE_AHASH, 63 .mode = SS_OP_SHA1, 64 .alg.hash = { 65 .init = sun4i_hash_init, 66 .update = sun4i_hash_update, 67 .final = sun4i_hash_final, 68 .finup = sun4i_hash_finup, 69 .digest = sun4i_hash_digest, 70 .export = sun4i_hash_export_sha1, 71 .import = sun4i_hash_import_sha1, 72 .halg = { 73 .digestsize = SHA1_DIGEST_SIZE, 74 .statesize = sizeof(struct sha1_state), 75 .base = { 76 .cra_name = "sha1", 77 .cra_driver_name = "sha1-sun4i-ss", 78 .cra_priority = 300, 79 .cra_alignmask = 3, 80 .cra_blocksize = SHA1_BLOCK_SIZE, 81 .cra_ctxsize = sizeof(struct sun4i_req_ctx), 82 .cra_module = THIS_MODULE, 83 .cra_init = sun4i_hash_crainit, 84 .cra_exit = sun4i_hash_craexit, 85 } 86 } 87 } 88 }, 89 { .type = CRYPTO_ALG_TYPE_SKCIPHER, 90 .alg.crypto = { 91 .setkey = sun4i_ss_aes_setkey, 92 .encrypt = sun4i_ss_cbc_aes_encrypt, 93 .decrypt = sun4i_ss_cbc_aes_decrypt, 94 .min_keysize = AES_MIN_KEY_SIZE, 95 .max_keysize = AES_MAX_KEY_SIZE, 96 .ivsize = AES_BLOCK_SIZE, 97 .base = { 98 .cra_name = "cbc(aes)", 99 .cra_driver_name = "cbc-aes-sun4i-ss", 100 .cra_priority = 300, 101 .cra_blocksize = AES_BLOCK_SIZE, 102 .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_NEED_FALLBACK, 103 .cra_ctxsize = sizeof(struct sun4i_tfm_ctx), 104 .cra_module = THIS_MODULE, 105 .cra_alignmask = 3, 106 .cra_init = sun4i_ss_cipher_init, 107 .cra_exit = sun4i_ss_cipher_exit, 108 } 109 } 110 }, 111 { .type = CRYPTO_ALG_TYPE_SKCIPHER, 112 .alg.crypto = { 113 .setkey = sun4i_ss_aes_setkey, 114 .encrypt = sun4i_ss_ecb_aes_encrypt, 115 .decrypt = sun4i_ss_ecb_aes_decrypt, 116 .min_keysize = AES_MIN_KEY_SIZE, 117 .max_keysize = AES_MAX_KEY_SIZE, 118 .base = { 119 .cra_name = "ecb(aes)", 120 .cra_driver_name = "ecb-aes-sun4i-ss", 121 .cra_priority = 300, 122 .cra_blocksize = AES_BLOCK_SIZE, 123 .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_NEED_FALLBACK, 124 .cra_ctxsize = sizeof(struct sun4i_tfm_ctx), 125 .cra_module = THIS_MODULE, 126 .cra_alignmask = 3, 127 .cra_init = sun4i_ss_cipher_init, 128 .cra_exit = sun4i_ss_cipher_exit, 129 } 130 } 131 }, 132 { .type = CRYPTO_ALG_TYPE_SKCIPHER, 133 .alg.crypto = { 134 .setkey = sun4i_ss_des_setkey, 135 .encrypt = sun4i_ss_cbc_des_encrypt, 136 .decrypt = sun4i_ss_cbc_des_decrypt, 137 .min_keysize = DES_KEY_SIZE, 138 .max_keysize = DES_KEY_SIZE, 139 .ivsize = DES_BLOCK_SIZE, 140 .base = { 141 .cra_name = "cbc(des)", 142 .cra_driver_name = "cbc-des-sun4i-ss", 143 .cra_priority = 300, 144 .cra_blocksize = DES_BLOCK_SIZE, 145 .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_NEED_FALLBACK, 146 .cra_ctxsize = sizeof(struct sun4i_req_ctx), 147 .cra_module = THIS_MODULE, 148 .cra_alignmask = 3, 149 .cra_init = sun4i_ss_cipher_init, 150 .cra_exit = sun4i_ss_cipher_exit, 151 } 152 } 153 }, 154 { .type = CRYPTO_ALG_TYPE_SKCIPHER, 155 .alg.crypto = { 156 .setkey = sun4i_ss_des_setkey, 157 .encrypt = sun4i_ss_ecb_des_encrypt, 158 .decrypt = sun4i_ss_ecb_des_decrypt, 159 .min_keysize = DES_KEY_SIZE, 160 .max_keysize = DES_KEY_SIZE, 161 .base = { 162 .cra_name = "ecb(des)", 163 .cra_driver_name = "ecb-des-sun4i-ss", 164 .cra_priority = 300, 165 .cra_blocksize = DES_BLOCK_SIZE, 166 .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_NEED_FALLBACK, 167 .cra_ctxsize = sizeof(struct sun4i_req_ctx), 168 .cra_module = THIS_MODULE, 169 .cra_alignmask = 3, 170 .cra_init = sun4i_ss_cipher_init, 171 .cra_exit = sun4i_ss_cipher_exit, 172 } 173 } 174 }, 175 { .type = CRYPTO_ALG_TYPE_SKCIPHER, 176 .alg.crypto = { 177 .setkey = sun4i_ss_des3_setkey, 178 .encrypt = sun4i_ss_cbc_des3_encrypt, 179 .decrypt = sun4i_ss_cbc_des3_decrypt, 180 .min_keysize = DES3_EDE_KEY_SIZE, 181 .max_keysize = DES3_EDE_KEY_SIZE, 182 .ivsize = DES3_EDE_BLOCK_SIZE, 183 .base = { 184 .cra_name = "cbc(des3_ede)", 185 .cra_driver_name = "cbc-des3-sun4i-ss", 186 .cra_priority = 300, 187 .cra_blocksize = DES3_EDE_BLOCK_SIZE, 188 .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_NEED_FALLBACK, 189 .cra_ctxsize = sizeof(struct sun4i_req_ctx), 190 .cra_module = THIS_MODULE, 191 .cra_alignmask = 3, 192 .cra_init = sun4i_ss_cipher_init, 193 .cra_exit = sun4i_ss_cipher_exit, 194 } 195 } 196 }, 197 { .type = CRYPTO_ALG_TYPE_SKCIPHER, 198 .alg.crypto = { 199 .setkey = sun4i_ss_des3_setkey, 200 .encrypt = sun4i_ss_ecb_des3_encrypt, 201 .decrypt = sun4i_ss_ecb_des3_decrypt, 202 .min_keysize = DES3_EDE_KEY_SIZE, 203 .max_keysize = DES3_EDE_KEY_SIZE, 204 .base = { 205 .cra_name = "ecb(des3_ede)", 206 .cra_driver_name = "ecb-des3-sun4i-ss", 207 .cra_priority = 300, 208 .cra_blocksize = DES3_EDE_BLOCK_SIZE, 209 .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_NEED_FALLBACK, 210 .cra_ctxsize = sizeof(struct sun4i_req_ctx), 211 .cra_module = THIS_MODULE, 212 .cra_alignmask = 3, 213 .cra_init = sun4i_ss_cipher_init, 214 .cra_exit = sun4i_ss_cipher_exit, 215 } 216 } 217 }, 218 #ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG 219 { 220 .type = CRYPTO_ALG_TYPE_RNG, 221 .alg.rng = { 222 .base = { 223 .cra_name = "stdrng", 224 .cra_driver_name = "sun4i_ss_rng", 225 .cra_priority = 300, 226 .cra_ctxsize = 0, 227 .cra_module = THIS_MODULE, 228 }, 229 .generate = sun4i_ss_prng_generate, 230 .seed = sun4i_ss_prng_seed, 231 .seedsize = SS_SEED_LEN / BITS_PER_BYTE, 232 } 233 }, 234 #endif 235 }; 236 237 static int sun4i_ss_debugfs_show(struct seq_file *seq, void *v) 238 { 239 unsigned int i; 240 241 for (i = 0; i < ARRAY_SIZE(ss_algs); i++) { 242 if (!ss_algs[i].ss) 243 continue; 244 switch (ss_algs[i].type) { 245 case CRYPTO_ALG_TYPE_SKCIPHER: 246 seq_printf(seq, "%s %s reqs=%lu opti=%lu fallback=%lu tsize=%lu\n", 247 ss_algs[i].alg.crypto.base.cra_driver_name, 248 ss_algs[i].alg.crypto.base.cra_name, 249 ss_algs[i].stat_req, ss_algs[i].stat_opti, ss_algs[i].stat_fb, 250 ss_algs[i].stat_bytes); 251 break; 252 case CRYPTO_ALG_TYPE_RNG: 253 seq_printf(seq, "%s %s reqs=%lu tsize=%lu\n", 254 ss_algs[i].alg.rng.base.cra_driver_name, 255 ss_algs[i].alg.rng.base.cra_name, 256 ss_algs[i].stat_req, ss_algs[i].stat_bytes); 257 break; 258 case CRYPTO_ALG_TYPE_AHASH: 259 seq_printf(seq, "%s %s reqs=%lu\n", 260 ss_algs[i].alg.hash.halg.base.cra_driver_name, 261 ss_algs[i].alg.hash.halg.base.cra_name, 262 ss_algs[i].stat_req); 263 break; 264 } 265 } 266 return 0; 267 } 268 DEFINE_SHOW_ATTRIBUTE(sun4i_ss_debugfs); 269 270 /* 271 * Power management strategy: The device is suspended unless a TFM exists for 272 * one of the algorithms proposed by this driver. 273 */ 274 static int sun4i_ss_pm_suspend(struct device *dev) 275 { 276 struct sun4i_ss_ctx *ss = dev_get_drvdata(dev); 277 278 reset_control_assert(ss->reset); 279 280 clk_disable_unprepare(ss->ssclk); 281 clk_disable_unprepare(ss->busclk); 282 return 0; 283 } 284 285 static int sun4i_ss_pm_resume(struct device *dev) 286 { 287 struct sun4i_ss_ctx *ss = dev_get_drvdata(dev); 288 289 int err; 290 291 err = clk_prepare_enable(ss->busclk); 292 if (err) { 293 dev_err(ss->dev, "Cannot prepare_enable busclk\n"); 294 goto err_enable; 295 } 296 297 err = clk_prepare_enable(ss->ssclk); 298 if (err) { 299 dev_err(ss->dev, "Cannot prepare_enable ssclk\n"); 300 goto err_enable; 301 } 302 303 err = reset_control_deassert(ss->reset); 304 if (err) { 305 dev_err(ss->dev, "Cannot deassert reset control\n"); 306 goto err_enable; 307 } 308 309 return err; 310 err_enable: 311 sun4i_ss_pm_suspend(dev); 312 return err; 313 } 314 315 static const struct dev_pm_ops sun4i_ss_pm_ops = { 316 SET_RUNTIME_PM_OPS(sun4i_ss_pm_suspend, sun4i_ss_pm_resume, NULL) 317 }; 318 319 /* 320 * When power management is enabled, this function enables the PM and set the 321 * device as suspended 322 * When power management is disabled, this function just enables the device 323 */ 324 static int sun4i_ss_pm_init(struct sun4i_ss_ctx *ss) 325 { 326 int err; 327 328 pm_runtime_use_autosuspend(ss->dev); 329 pm_runtime_set_autosuspend_delay(ss->dev, 2000); 330 331 err = pm_runtime_set_suspended(ss->dev); 332 if (err) 333 return err; 334 pm_runtime_enable(ss->dev); 335 return err; 336 } 337 338 static void sun4i_ss_pm_exit(struct sun4i_ss_ctx *ss) 339 { 340 pm_runtime_disable(ss->dev); 341 } 342 343 static int sun4i_ss_probe(struct platform_device *pdev) 344 { 345 u32 v; 346 int err, i; 347 unsigned long cr; 348 const unsigned long cr_ahb = 24 * 1000 * 1000; 349 const unsigned long cr_mod = 150 * 1000 * 1000; 350 struct sun4i_ss_ctx *ss; 351 352 if (!pdev->dev.of_node) 353 return -ENODEV; 354 355 ss = devm_kzalloc(&pdev->dev, sizeof(*ss), GFP_KERNEL); 356 if (!ss) 357 return -ENOMEM; 358 359 ss->base = devm_platform_ioremap_resource(pdev, 0); 360 if (IS_ERR(ss->base)) { 361 dev_err(&pdev->dev, "Cannot request MMIO\n"); 362 return PTR_ERR(ss->base); 363 } 364 365 ss->variant = of_device_get_match_data(&pdev->dev); 366 if (!ss->variant) { 367 dev_err(&pdev->dev, "Missing Security System variant\n"); 368 return -EINVAL; 369 } 370 371 ss->ssclk = devm_clk_get(&pdev->dev, "mod"); 372 if (IS_ERR(ss->ssclk)) { 373 err = PTR_ERR(ss->ssclk); 374 dev_err(&pdev->dev, "Cannot get SS clock err=%d\n", err); 375 return err; 376 } 377 dev_dbg(&pdev->dev, "clock ss acquired\n"); 378 379 ss->busclk = devm_clk_get(&pdev->dev, "ahb"); 380 if (IS_ERR(ss->busclk)) { 381 err = PTR_ERR(ss->busclk); 382 dev_err(&pdev->dev, "Cannot get AHB SS clock err=%d\n", err); 383 return err; 384 } 385 dev_dbg(&pdev->dev, "clock ahb_ss acquired\n"); 386 387 ss->reset = devm_reset_control_get_optional(&pdev->dev, "ahb"); 388 if (IS_ERR(ss->reset)) 389 return PTR_ERR(ss->reset); 390 if (!ss->reset) 391 dev_info(&pdev->dev, "no reset control found\n"); 392 393 /* 394 * Check that clock have the correct rates given in the datasheet 395 * Try to set the clock to the maximum allowed 396 */ 397 err = clk_set_rate(ss->ssclk, cr_mod); 398 if (err) { 399 dev_err(&pdev->dev, "Cannot set clock rate to ssclk\n"); 400 return err; 401 } 402 403 /* 404 * The only impact on clocks below requirement are bad performance, 405 * so do not print "errors" 406 * warn on Overclocked clocks 407 */ 408 cr = clk_get_rate(ss->busclk); 409 if (cr >= cr_ahb) 410 dev_dbg(&pdev->dev, "Clock bus %lu (%lu MHz) (must be >= %lu)\n", 411 cr, cr / 1000000, cr_ahb); 412 else 413 dev_warn(&pdev->dev, "Clock bus %lu (%lu MHz) (must be >= %lu)\n", 414 cr, cr / 1000000, cr_ahb); 415 416 cr = clk_get_rate(ss->ssclk); 417 if (cr <= cr_mod) 418 if (cr < cr_mod) 419 dev_warn(&pdev->dev, "Clock ss %lu (%lu MHz) (must be <= %lu)\n", 420 cr, cr / 1000000, cr_mod); 421 else 422 dev_dbg(&pdev->dev, "Clock ss %lu (%lu MHz) (must be <= %lu)\n", 423 cr, cr / 1000000, cr_mod); 424 else 425 dev_warn(&pdev->dev, "Clock ss is at %lu (%lu MHz) (must be <= %lu)\n", 426 cr, cr / 1000000, cr_mod); 427 428 ss->dev = &pdev->dev; 429 platform_set_drvdata(pdev, ss); 430 431 spin_lock_init(&ss->slock); 432 433 err = sun4i_ss_pm_init(ss); 434 if (err) 435 return err; 436 437 /* 438 * Datasheet named it "Die Bonding ID" 439 * I expect to be a sort of Security System Revision number. 440 * Since the A80 seems to have an other version of SS 441 * this info could be useful 442 */ 443 444 err = pm_runtime_resume_and_get(ss->dev); 445 if (err < 0) 446 goto error_pm; 447 448 writel(SS_ENABLED, ss->base + SS_CTL); 449 v = readl(ss->base + SS_CTL); 450 v >>= 16; 451 v &= 0x07; 452 dev_info(&pdev->dev, "Die ID %d\n", v); 453 writel(0, ss->base + SS_CTL); 454 455 pm_runtime_put_sync(ss->dev); 456 457 for (i = 0; i < ARRAY_SIZE(ss_algs); i++) { 458 ss_algs[i].ss = ss; 459 switch (ss_algs[i].type) { 460 case CRYPTO_ALG_TYPE_SKCIPHER: 461 err = crypto_register_skcipher(&ss_algs[i].alg.crypto); 462 if (err) { 463 dev_err(ss->dev, "Fail to register %s\n", 464 ss_algs[i].alg.crypto.base.cra_name); 465 goto error_alg; 466 } 467 break; 468 case CRYPTO_ALG_TYPE_AHASH: 469 err = crypto_register_ahash(&ss_algs[i].alg.hash); 470 if (err) { 471 dev_err(ss->dev, "Fail to register %s\n", 472 ss_algs[i].alg.hash.halg.base.cra_name); 473 goto error_alg; 474 } 475 break; 476 case CRYPTO_ALG_TYPE_RNG: 477 err = crypto_register_rng(&ss_algs[i].alg.rng); 478 if (err) { 479 dev_err(ss->dev, "Fail to register %s\n", 480 ss_algs[i].alg.rng.base.cra_name); 481 } 482 break; 483 } 484 } 485 486 /* Ignore error of debugfs */ 487 ss->dbgfs_dir = debugfs_create_dir("sun4i-ss", NULL); 488 ss->dbgfs_stats = debugfs_create_file("stats", 0444, ss->dbgfs_dir, ss, 489 &sun4i_ss_debugfs_fops); 490 491 return 0; 492 error_alg: 493 i--; 494 for (; i >= 0; i--) { 495 switch (ss_algs[i].type) { 496 case CRYPTO_ALG_TYPE_SKCIPHER: 497 crypto_unregister_skcipher(&ss_algs[i].alg.crypto); 498 break; 499 case CRYPTO_ALG_TYPE_AHASH: 500 crypto_unregister_ahash(&ss_algs[i].alg.hash); 501 break; 502 case CRYPTO_ALG_TYPE_RNG: 503 crypto_unregister_rng(&ss_algs[i].alg.rng); 504 break; 505 } 506 } 507 error_pm: 508 sun4i_ss_pm_exit(ss); 509 return err; 510 } 511 512 static int sun4i_ss_remove(struct platform_device *pdev) 513 { 514 int i; 515 struct sun4i_ss_ctx *ss = platform_get_drvdata(pdev); 516 517 for (i = 0; i < ARRAY_SIZE(ss_algs); i++) { 518 switch (ss_algs[i].type) { 519 case CRYPTO_ALG_TYPE_SKCIPHER: 520 crypto_unregister_skcipher(&ss_algs[i].alg.crypto); 521 break; 522 case CRYPTO_ALG_TYPE_AHASH: 523 crypto_unregister_ahash(&ss_algs[i].alg.hash); 524 break; 525 case CRYPTO_ALG_TYPE_RNG: 526 crypto_unregister_rng(&ss_algs[i].alg.rng); 527 break; 528 } 529 } 530 531 sun4i_ss_pm_exit(ss); 532 return 0; 533 } 534 535 static const struct of_device_id a20ss_crypto_of_match_table[] = { 536 { .compatible = "allwinner,sun4i-a10-crypto", 537 .data = &ss_a10_variant 538 }, 539 { .compatible = "allwinner,sun8i-a33-crypto", 540 .data = &ss_a33_variant 541 }, 542 {} 543 }; 544 MODULE_DEVICE_TABLE(of, a20ss_crypto_of_match_table); 545 546 static struct platform_driver sun4i_ss_driver = { 547 .probe = sun4i_ss_probe, 548 .remove = sun4i_ss_remove, 549 .driver = { 550 .name = "sun4i-ss", 551 .pm = &sun4i_ss_pm_ops, 552 .of_match_table = a20ss_crypto_of_match_table, 553 }, 554 }; 555 556 module_platform_driver(sun4i_ss_driver); 557 558 MODULE_ALIAS("platform:sun4i-ss"); 559 MODULE_DESCRIPTION("Allwinner Security System cryptographic accelerator"); 560 MODULE_LICENSE("GPL"); 561 MODULE_AUTHOR("Corentin LABBE <clabbe.montjoie@gmail.com>"); 562