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/arm/sunxi.rst
10  */
11 #include <linux/clk.h>
12 #include <linux/crypto.h>
13 #include <linux/io.h>
14 #include <linux/module.h>
15 #include <linux/of.h>
16 #include <linux/platform_device.h>
17 #include <crypto/scatterwalk.h>
18 #include <linux/scatterlist.h>
19 #include <linux/interrupt.h>
20 #include <linux/delay.h>
21 #include <linux/reset.h>
22 
23 #include "sun4i-ss.h"
24 
25 static struct sun4i_ss_alg_template ss_algs[] = {
26 {       .type = CRYPTO_ALG_TYPE_AHASH,
27 	.mode = SS_OP_MD5,
28 	.alg.hash = {
29 		.init = sun4i_hash_init,
30 		.update = sun4i_hash_update,
31 		.final = sun4i_hash_final,
32 		.finup = sun4i_hash_finup,
33 		.digest = sun4i_hash_digest,
34 		.export = sun4i_hash_export_md5,
35 		.import = sun4i_hash_import_md5,
36 		.halg = {
37 			.digestsize = MD5_DIGEST_SIZE,
38 			.statesize = sizeof(struct md5_state),
39 			.base = {
40 				.cra_name = "md5",
41 				.cra_driver_name = "md5-sun4i-ss",
42 				.cra_priority = 300,
43 				.cra_alignmask = 3,
44 				.cra_blocksize = MD5_HMAC_BLOCK_SIZE,
45 				.cra_ctxsize = sizeof(struct sun4i_req_ctx),
46 				.cra_module = THIS_MODULE,
47 				.cra_init = sun4i_hash_crainit
48 			}
49 		}
50 	}
51 },
52 {       .type = CRYPTO_ALG_TYPE_AHASH,
53 	.mode = SS_OP_SHA1,
54 	.alg.hash = {
55 		.init = sun4i_hash_init,
56 		.update = sun4i_hash_update,
57 		.final = sun4i_hash_final,
58 		.finup = sun4i_hash_finup,
59 		.digest = sun4i_hash_digest,
60 		.export = sun4i_hash_export_sha1,
61 		.import = sun4i_hash_import_sha1,
62 		.halg = {
63 			.digestsize = SHA1_DIGEST_SIZE,
64 			.statesize = sizeof(struct sha1_state),
65 			.base = {
66 				.cra_name = "sha1",
67 				.cra_driver_name = "sha1-sun4i-ss",
68 				.cra_priority = 300,
69 				.cra_alignmask = 3,
70 				.cra_blocksize = SHA1_BLOCK_SIZE,
71 				.cra_ctxsize = sizeof(struct sun4i_req_ctx),
72 				.cra_module = THIS_MODULE,
73 				.cra_init = sun4i_hash_crainit
74 			}
75 		}
76 	}
77 },
78 {       .type = CRYPTO_ALG_TYPE_SKCIPHER,
79 	.alg.crypto = {
80 		.setkey         = sun4i_ss_aes_setkey,
81 		.encrypt        = sun4i_ss_cbc_aes_encrypt,
82 		.decrypt        = sun4i_ss_cbc_aes_decrypt,
83 		.min_keysize	= AES_MIN_KEY_SIZE,
84 		.max_keysize	= AES_MAX_KEY_SIZE,
85 		.ivsize		= AES_BLOCK_SIZE,
86 		.base = {
87 			.cra_name = "cbc(aes)",
88 			.cra_driver_name = "cbc-aes-sun4i-ss",
89 			.cra_priority = 300,
90 			.cra_blocksize = AES_BLOCK_SIZE,
91 			.cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_NEED_FALLBACK,
92 			.cra_ctxsize = sizeof(struct sun4i_tfm_ctx),
93 			.cra_module = THIS_MODULE,
94 			.cra_alignmask = 3,
95 			.cra_init = sun4i_ss_cipher_init,
96 			.cra_exit = sun4i_ss_cipher_exit,
97 		}
98 	}
99 },
100 {       .type = CRYPTO_ALG_TYPE_SKCIPHER,
101 	.alg.crypto = {
102 		.setkey         = sun4i_ss_aes_setkey,
103 		.encrypt        = sun4i_ss_ecb_aes_encrypt,
104 		.decrypt        = sun4i_ss_ecb_aes_decrypt,
105 		.min_keysize	= AES_MIN_KEY_SIZE,
106 		.max_keysize	= AES_MAX_KEY_SIZE,
107 		.base = {
108 			.cra_name = "ecb(aes)",
109 			.cra_driver_name = "ecb-aes-sun4i-ss",
110 			.cra_priority = 300,
111 			.cra_blocksize = AES_BLOCK_SIZE,
112 			.cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_NEED_FALLBACK,
113 			.cra_ctxsize = sizeof(struct sun4i_tfm_ctx),
114 			.cra_module = THIS_MODULE,
115 			.cra_alignmask = 3,
116 			.cra_init = sun4i_ss_cipher_init,
117 			.cra_exit = sun4i_ss_cipher_exit,
118 		}
119 	}
120 },
121 {       .type = CRYPTO_ALG_TYPE_SKCIPHER,
122 	.alg.crypto = {
123 		.setkey         = sun4i_ss_des_setkey,
124 		.encrypt        = sun4i_ss_cbc_des_encrypt,
125 		.decrypt        = sun4i_ss_cbc_des_decrypt,
126 		.min_keysize    = DES_KEY_SIZE,
127 		.max_keysize    = DES_KEY_SIZE,
128 		.ivsize         = DES_BLOCK_SIZE,
129 		.base = {
130 			.cra_name = "cbc(des)",
131 			.cra_driver_name = "cbc-des-sun4i-ss",
132 			.cra_priority = 300,
133 			.cra_blocksize = DES_BLOCK_SIZE,
134 			.cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_NEED_FALLBACK,
135 			.cra_ctxsize = sizeof(struct sun4i_req_ctx),
136 			.cra_module = THIS_MODULE,
137 			.cra_alignmask = 3,
138 			.cra_init = sun4i_ss_cipher_init,
139 			.cra_exit = sun4i_ss_cipher_exit,
140 		}
141 	}
142 },
143 {       .type = CRYPTO_ALG_TYPE_SKCIPHER,
144 	.alg.crypto = {
145 		.setkey         = sun4i_ss_des_setkey,
146 		.encrypt        = sun4i_ss_ecb_des_encrypt,
147 		.decrypt        = sun4i_ss_ecb_des_decrypt,
148 		.min_keysize    = DES_KEY_SIZE,
149 		.max_keysize    = DES_KEY_SIZE,
150 		.base = {
151 			.cra_name = "ecb(des)",
152 			.cra_driver_name = "ecb-des-sun4i-ss",
153 			.cra_priority = 300,
154 			.cra_blocksize = DES_BLOCK_SIZE,
155 			.cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_NEED_FALLBACK,
156 			.cra_ctxsize = sizeof(struct sun4i_req_ctx),
157 			.cra_module = THIS_MODULE,
158 			.cra_alignmask = 3,
159 			.cra_init = sun4i_ss_cipher_init,
160 			.cra_exit = sun4i_ss_cipher_exit,
161 		}
162 	}
163 },
164 {       .type = CRYPTO_ALG_TYPE_SKCIPHER,
165 	.alg.crypto = {
166 		.setkey         = sun4i_ss_des3_setkey,
167 		.encrypt        = sun4i_ss_cbc_des3_encrypt,
168 		.decrypt        = sun4i_ss_cbc_des3_decrypt,
169 		.min_keysize    = DES3_EDE_KEY_SIZE,
170 		.max_keysize    = DES3_EDE_KEY_SIZE,
171 		.ivsize         = DES3_EDE_BLOCK_SIZE,
172 		.base = {
173 			.cra_name = "cbc(des3_ede)",
174 			.cra_driver_name = "cbc-des3-sun4i-ss",
175 			.cra_priority = 300,
176 			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
177 			.cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_NEED_FALLBACK,
178 			.cra_ctxsize = sizeof(struct sun4i_req_ctx),
179 			.cra_module = THIS_MODULE,
180 			.cra_alignmask = 3,
181 			.cra_init = sun4i_ss_cipher_init,
182 			.cra_exit = sun4i_ss_cipher_exit,
183 		}
184 	}
185 },
186 {       .type = CRYPTO_ALG_TYPE_SKCIPHER,
187 	.alg.crypto = {
188 		.setkey         = sun4i_ss_des3_setkey,
189 		.encrypt        = sun4i_ss_ecb_des3_encrypt,
190 		.decrypt        = sun4i_ss_ecb_des3_decrypt,
191 		.min_keysize    = DES3_EDE_KEY_SIZE,
192 		.max_keysize    = DES3_EDE_KEY_SIZE,
193 		.base = {
194 			.cra_name = "ecb(des3_ede)",
195 			.cra_driver_name = "ecb-des3-sun4i-ss",
196 			.cra_priority = 300,
197 			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
198 			.cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_NEED_FALLBACK,
199 			.cra_ctxsize = sizeof(struct sun4i_req_ctx),
200 			.cra_module = THIS_MODULE,
201 			.cra_alignmask = 3,
202 			.cra_init = sun4i_ss_cipher_init,
203 			.cra_exit = sun4i_ss_cipher_exit,
204 		}
205 	}
206 },
207 #ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG
208 {
209 	.type = CRYPTO_ALG_TYPE_RNG,
210 	.alg.rng = {
211 		.base = {
212 			.cra_name		= "stdrng",
213 			.cra_driver_name	= "sun4i_ss_rng",
214 			.cra_priority		= 300,
215 			.cra_ctxsize		= 0,
216 			.cra_module		= THIS_MODULE,
217 		},
218 		.generate               = sun4i_ss_prng_generate,
219 		.seed                   = sun4i_ss_prng_seed,
220 		.seedsize               = SS_SEED_LEN / BITS_PER_BYTE,
221 	}
222 },
223 #endif
224 };
225 
sun4i_ss_probe(struct platform_device * pdev)226 static int sun4i_ss_probe(struct platform_device *pdev)
227 {
228 	u32 v;
229 	int err, i;
230 	unsigned long cr;
231 	const unsigned long cr_ahb = 24 * 1000 * 1000;
232 	const unsigned long cr_mod = 150 * 1000 * 1000;
233 	struct sun4i_ss_ctx *ss;
234 
235 	if (!pdev->dev.of_node)
236 		return -ENODEV;
237 
238 	ss = devm_kzalloc(&pdev->dev, sizeof(*ss), GFP_KERNEL);
239 	if (!ss)
240 		return -ENOMEM;
241 
242 	ss->base = devm_platform_ioremap_resource(pdev, 0);
243 	if (IS_ERR(ss->base)) {
244 		dev_err(&pdev->dev, "Cannot request MMIO\n");
245 		return PTR_ERR(ss->base);
246 	}
247 
248 	ss->ssclk = devm_clk_get(&pdev->dev, "mod");
249 	if (IS_ERR(ss->ssclk)) {
250 		err = PTR_ERR(ss->ssclk);
251 		dev_err(&pdev->dev, "Cannot get SS clock err=%d\n", err);
252 		return err;
253 	}
254 	dev_dbg(&pdev->dev, "clock ss acquired\n");
255 
256 	ss->busclk = devm_clk_get(&pdev->dev, "ahb");
257 	if (IS_ERR(ss->busclk)) {
258 		err = PTR_ERR(ss->busclk);
259 		dev_err(&pdev->dev, "Cannot get AHB SS clock err=%d\n", err);
260 		return err;
261 	}
262 	dev_dbg(&pdev->dev, "clock ahb_ss acquired\n");
263 
264 	ss->reset = devm_reset_control_get_optional(&pdev->dev, "ahb");
265 	if (IS_ERR(ss->reset)) {
266 		if (PTR_ERR(ss->reset) == -EPROBE_DEFER)
267 			return PTR_ERR(ss->reset);
268 		dev_info(&pdev->dev, "no reset control found\n");
269 		ss->reset = NULL;
270 	}
271 
272 	/* Enable both clocks */
273 	err = clk_prepare_enable(ss->busclk);
274 	if (err) {
275 		dev_err(&pdev->dev, "Cannot prepare_enable busclk\n");
276 		return err;
277 	}
278 	err = clk_prepare_enable(ss->ssclk);
279 	if (err) {
280 		dev_err(&pdev->dev, "Cannot prepare_enable ssclk\n");
281 		goto error_ssclk;
282 	}
283 
284 	/*
285 	 * Check that clock have the correct rates given in the datasheet
286 	 * Try to set the clock to the maximum allowed
287 	 */
288 	err = clk_set_rate(ss->ssclk, cr_mod);
289 	if (err) {
290 		dev_err(&pdev->dev, "Cannot set clock rate to ssclk\n");
291 		goto error_clk;
292 	}
293 
294 	/* Deassert reset if we have a reset control */
295 	if (ss->reset) {
296 		err = reset_control_deassert(ss->reset);
297 		if (err) {
298 			dev_err(&pdev->dev, "Cannot deassert reset control\n");
299 			goto error_clk;
300 		}
301 	}
302 
303 	/*
304 	 * The only impact on clocks below requirement are bad performance,
305 	 * so do not print "errors"
306 	 * warn on Overclocked clocks
307 	 */
308 	cr = clk_get_rate(ss->busclk);
309 	if (cr >= cr_ahb)
310 		dev_dbg(&pdev->dev, "Clock bus %lu (%lu MHz) (must be >= %lu)\n",
311 			cr, cr / 1000000, cr_ahb);
312 	else
313 		dev_warn(&pdev->dev, "Clock bus %lu (%lu MHz) (must be >= %lu)\n",
314 			 cr, cr / 1000000, cr_ahb);
315 
316 	cr = clk_get_rate(ss->ssclk);
317 	if (cr <= cr_mod)
318 		if (cr < cr_mod)
319 			dev_warn(&pdev->dev, "Clock ss %lu (%lu MHz) (must be <= %lu)\n",
320 				 cr, cr / 1000000, cr_mod);
321 		else
322 			dev_dbg(&pdev->dev, "Clock ss %lu (%lu MHz) (must be <= %lu)\n",
323 				cr, cr / 1000000, cr_mod);
324 	else
325 		dev_warn(&pdev->dev, "Clock ss is at %lu (%lu MHz) (must be <= %lu)\n",
326 			 cr, cr / 1000000, cr_mod);
327 
328 	/*
329 	 * Datasheet named it "Die Bonding ID"
330 	 * I expect to be a sort of Security System Revision number.
331 	 * Since the A80 seems to have an other version of SS
332 	 * this info could be useful
333 	 */
334 	writel(SS_ENABLED, ss->base + SS_CTL);
335 	v = readl(ss->base + SS_CTL);
336 	v >>= 16;
337 	v &= 0x07;
338 	dev_info(&pdev->dev, "Die ID %d\n", v);
339 	writel(0, ss->base + SS_CTL);
340 
341 	ss->dev = &pdev->dev;
342 
343 	spin_lock_init(&ss->slock);
344 
345 	for (i = 0; i < ARRAY_SIZE(ss_algs); i++) {
346 		ss_algs[i].ss = ss;
347 		switch (ss_algs[i].type) {
348 		case CRYPTO_ALG_TYPE_SKCIPHER:
349 			err = crypto_register_skcipher(&ss_algs[i].alg.crypto);
350 			if (err) {
351 				dev_err(ss->dev, "Fail to register %s\n",
352 					ss_algs[i].alg.crypto.base.cra_name);
353 				goto error_alg;
354 			}
355 			break;
356 		case CRYPTO_ALG_TYPE_AHASH:
357 			err = crypto_register_ahash(&ss_algs[i].alg.hash);
358 			if (err) {
359 				dev_err(ss->dev, "Fail to register %s\n",
360 					ss_algs[i].alg.hash.halg.base.cra_name);
361 				goto error_alg;
362 			}
363 			break;
364 		case CRYPTO_ALG_TYPE_RNG:
365 			err = crypto_register_rng(&ss_algs[i].alg.rng);
366 			if (err) {
367 				dev_err(ss->dev, "Fail to register %s\n",
368 					ss_algs[i].alg.rng.base.cra_name);
369 			}
370 			break;
371 		}
372 	}
373 	platform_set_drvdata(pdev, ss);
374 	return 0;
375 error_alg:
376 	i--;
377 	for (; i >= 0; i--) {
378 		switch (ss_algs[i].type) {
379 		case CRYPTO_ALG_TYPE_SKCIPHER:
380 			crypto_unregister_skcipher(&ss_algs[i].alg.crypto);
381 			break;
382 		case CRYPTO_ALG_TYPE_AHASH:
383 			crypto_unregister_ahash(&ss_algs[i].alg.hash);
384 			break;
385 		case CRYPTO_ALG_TYPE_RNG:
386 			crypto_unregister_rng(&ss_algs[i].alg.rng);
387 			break;
388 		}
389 	}
390 	if (ss->reset)
391 		reset_control_assert(ss->reset);
392 error_clk:
393 	clk_disable_unprepare(ss->ssclk);
394 error_ssclk:
395 	clk_disable_unprepare(ss->busclk);
396 	return err;
397 }
398 
sun4i_ss_remove(struct platform_device * pdev)399 static int sun4i_ss_remove(struct platform_device *pdev)
400 {
401 	int i;
402 	struct sun4i_ss_ctx *ss = platform_get_drvdata(pdev);
403 
404 	for (i = 0; i < ARRAY_SIZE(ss_algs); i++) {
405 		switch (ss_algs[i].type) {
406 		case CRYPTO_ALG_TYPE_SKCIPHER:
407 			crypto_unregister_skcipher(&ss_algs[i].alg.crypto);
408 			break;
409 		case CRYPTO_ALG_TYPE_AHASH:
410 			crypto_unregister_ahash(&ss_algs[i].alg.hash);
411 			break;
412 		case CRYPTO_ALG_TYPE_RNG:
413 			crypto_unregister_rng(&ss_algs[i].alg.rng);
414 			break;
415 		}
416 	}
417 
418 	writel(0, ss->base + SS_CTL);
419 	if (ss->reset)
420 		reset_control_assert(ss->reset);
421 	clk_disable_unprepare(ss->busclk);
422 	clk_disable_unprepare(ss->ssclk);
423 	return 0;
424 }
425 
426 static const struct of_device_id a20ss_crypto_of_match_table[] = {
427 	{ .compatible = "allwinner,sun4i-a10-crypto" },
428 	{}
429 };
430 MODULE_DEVICE_TABLE(of, a20ss_crypto_of_match_table);
431 
432 static struct platform_driver sun4i_ss_driver = {
433 	.probe          = sun4i_ss_probe,
434 	.remove         = sun4i_ss_remove,
435 	.driver         = {
436 		.name           = "sun4i-ss",
437 		.of_match_table	= a20ss_crypto_of_match_table,
438 	},
439 };
440 
441 module_platform_driver(sun4i_ss_driver);
442 
443 MODULE_ALIAS("platform:sun4i-ss");
444 MODULE_DESCRIPTION("Allwinner Security System cryptographic accelerator");
445 MODULE_LICENSE("GPL");
446 MODULE_AUTHOR("Corentin LABBE <clabbe.montjoie@gmail.com>");
447