xref: /rk3399_rockchip-uboot/drivers/crypto/crypto-uclass.c (revision 434d6fd368d76f3bfc507c4bb84476a53cfac992)
1cc6ac5d6SJoseph Chen // SPDX-License-Identifier: GPL-2.0
2cc6ac5d6SJoseph Chen /*
3cc6ac5d6SJoseph Chen  * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
4cc6ac5d6SJoseph Chen  */
5cc6ac5d6SJoseph Chen 
6cc6ac5d6SJoseph Chen #include <common.h>
7cc6ac5d6SJoseph Chen #include <crypto.h>
8cc6ac5d6SJoseph Chen #include <dm.h>
9cc6ac5d6SJoseph Chen #include <u-boot/sha1.h>
10cc6ac5d6SJoseph Chen 
11cc6ac5d6SJoseph Chen u32 crypto_algo_nbits(u32 algo)
12cc6ac5d6SJoseph Chen {
13cc6ac5d6SJoseph Chen 	switch (algo) {
14cc6ac5d6SJoseph Chen 	case CRYPTO_MD5:
15cc6ac5d6SJoseph Chen 		return 128;
16cc6ac5d6SJoseph Chen 	case CRYPTO_SHA1:
17cc6ac5d6SJoseph Chen 		return 160;
18cc6ac5d6SJoseph Chen 	case CRYPTO_SHA256:
19cc6ac5d6SJoseph Chen 		return 256;
20e7846385SLin Jinhan 	case CRYPTO_SHA512:
21e7846385SLin Jinhan 		return 512;
22cc6ac5d6SJoseph Chen 	case CRYPTO_RSA512:
23cc6ac5d6SJoseph Chen 		return 512;
24cc6ac5d6SJoseph Chen 	case CRYPTO_RSA1024:
25cc6ac5d6SJoseph Chen 		return 1024;
26cc6ac5d6SJoseph Chen 	case CRYPTO_RSA2048:
27cc6ac5d6SJoseph Chen 		return 2048;
28b353a43cSLin Jinhan 	case CRYPTO_RSA3072:
29b353a43cSLin Jinhan 		return 3072;
30b353a43cSLin Jinhan 	case CRYPTO_RSA4096:
31b353a43cSLin Jinhan 		return 4096;
32cc6ac5d6SJoseph Chen 	}
33cc6ac5d6SJoseph Chen 
34cc6ac5d6SJoseph Chen 	printf("Unknown crypto algorithm: 0x%x\n", algo);
35cc6ac5d6SJoseph Chen 
36cc6ac5d6SJoseph Chen 	return 0;
37cc6ac5d6SJoseph Chen }
38cc6ac5d6SJoseph Chen 
39cc6ac5d6SJoseph Chen struct udevice *crypto_get_device(u32 capability)
40cc6ac5d6SJoseph Chen {
41cc6ac5d6SJoseph Chen 	const struct dm_crypto_ops *ops;
42cc6ac5d6SJoseph Chen 	struct udevice *dev;
43cc6ac5d6SJoseph Chen 	struct uclass *uc;
44cc6ac5d6SJoseph Chen 	int ret;
45cc6ac5d6SJoseph Chen 	u32 cap;
46cc6ac5d6SJoseph Chen 
47cc6ac5d6SJoseph Chen 	ret = uclass_get(UCLASS_CRYPTO, &uc);
48cc6ac5d6SJoseph Chen 	if (ret)
49cc6ac5d6SJoseph Chen 		return NULL;
50cc6ac5d6SJoseph Chen 
51cc6ac5d6SJoseph Chen 	for (uclass_first_device(UCLASS_CRYPTO, &dev);
52cc6ac5d6SJoseph Chen 	     dev;
53cc6ac5d6SJoseph Chen 	     uclass_next_device(&dev)) {
54cc6ac5d6SJoseph Chen 		ops = device_get_ops(dev);
55cc6ac5d6SJoseph Chen 		if (!ops || !ops->capability)
56cc6ac5d6SJoseph Chen 			continue;
57cc6ac5d6SJoseph Chen 
58cc6ac5d6SJoseph Chen 		cap = ops->capability(dev);
59cc6ac5d6SJoseph Chen 		if ((cap & capability) == capability)
60cc6ac5d6SJoseph Chen 			return dev;
61cc6ac5d6SJoseph Chen 	}
62cc6ac5d6SJoseph Chen 
63cc6ac5d6SJoseph Chen 	return NULL;
64cc6ac5d6SJoseph Chen }
65cc6ac5d6SJoseph Chen 
66cc6ac5d6SJoseph Chen int crypto_sha_init(struct udevice *dev, sha_context *ctx)
67cc6ac5d6SJoseph Chen {
68cc6ac5d6SJoseph Chen 	const struct dm_crypto_ops *ops = device_get_ops(dev);
69cc6ac5d6SJoseph Chen 
70cc6ac5d6SJoseph Chen 	if (!ops || !ops->sha_init)
71cc6ac5d6SJoseph Chen 		return -ENOSYS;
72cc6ac5d6SJoseph Chen 
73cc6ac5d6SJoseph Chen 	return ops->sha_init(dev, ctx);
74cc6ac5d6SJoseph Chen }
75cc6ac5d6SJoseph Chen 
76cc6ac5d6SJoseph Chen int crypto_sha_update(struct udevice *dev, u32 *input, u32 len)
77cc6ac5d6SJoseph Chen {
78cc6ac5d6SJoseph Chen 	const struct dm_crypto_ops *ops = device_get_ops(dev);
79cc6ac5d6SJoseph Chen 
80cc6ac5d6SJoseph Chen 	if (!ops || !ops->sha_update)
81cc6ac5d6SJoseph Chen 		return -ENOSYS;
82cc6ac5d6SJoseph Chen 
83cc6ac5d6SJoseph Chen 	return ops->sha_update(dev, input, len);
84cc6ac5d6SJoseph Chen }
85cc6ac5d6SJoseph Chen 
86cc6ac5d6SJoseph Chen int crypto_sha_final(struct udevice *dev, sha_context *ctx, u8 *output)
87cc6ac5d6SJoseph Chen {
88cc6ac5d6SJoseph Chen 	const struct dm_crypto_ops *ops = device_get_ops(dev);
89cc6ac5d6SJoseph Chen 
90cc6ac5d6SJoseph Chen 	if (!ops || !ops->sha_final)
91cc6ac5d6SJoseph Chen 		return -ENOSYS;
92cc6ac5d6SJoseph Chen 
93cc6ac5d6SJoseph Chen 	return ops->sha_final(dev, ctx, output);
94cc6ac5d6SJoseph Chen }
95cc6ac5d6SJoseph Chen 
96cc6ac5d6SJoseph Chen int crypto_sha_csum(struct udevice *dev, sha_context *ctx,
97cc6ac5d6SJoseph Chen 		    char *input, u32 input_len, u8 *output)
98cc6ac5d6SJoseph Chen {
99cc6ac5d6SJoseph Chen 	int ret;
100cc6ac5d6SJoseph Chen 
101cc6ac5d6SJoseph Chen 	ret = crypto_sha_init(dev, ctx);
102cc6ac5d6SJoseph Chen 	if (ret)
103cc6ac5d6SJoseph Chen 		return ret;
104cc6ac5d6SJoseph Chen 
105cc6ac5d6SJoseph Chen 	ret = crypto_sha_update(dev, (u32 *)input, input_len);
106cc6ac5d6SJoseph Chen 	if (ret)
107cc6ac5d6SJoseph Chen 		return ret;
108cc6ac5d6SJoseph Chen 
109cc6ac5d6SJoseph Chen 	ret = crypto_sha_final(dev, ctx, output);
110cc6ac5d6SJoseph Chen 
111cc6ac5d6SJoseph Chen 	return ret;
112cc6ac5d6SJoseph Chen }
113cc6ac5d6SJoseph Chen 
114cc6ac5d6SJoseph Chen int crypto_rsa_verify(struct udevice *dev, rsa_key *ctx, u8 *sign, u8 *output)
115cc6ac5d6SJoseph Chen {
116cc6ac5d6SJoseph Chen 	const struct dm_crypto_ops *ops = device_get_ops(dev);
117cc6ac5d6SJoseph Chen 
118cc6ac5d6SJoseph Chen 	if (!ops || !ops->rsa_verify)
119cc6ac5d6SJoseph Chen 		return -ENOSYS;
120cc6ac5d6SJoseph Chen 
121cc6ac5d6SJoseph Chen 	return ops->rsa_verify(dev, ctx, sign, output);
122cc6ac5d6SJoseph Chen }
123cc6ac5d6SJoseph Chen 
124*434d6fd3SLin Jinhan int crypto_get_trng(struct udevice *dev, u8 *output, u32 len)
125*434d6fd3SLin Jinhan {
126*434d6fd3SLin Jinhan 	const struct dm_crypto_ops *ops = device_get_ops(dev);
127*434d6fd3SLin Jinhan 
128*434d6fd3SLin Jinhan 	if (!ops || !ops->get_trng)
129*434d6fd3SLin Jinhan 		return -ENOSYS;
130*434d6fd3SLin Jinhan 
131*434d6fd3SLin Jinhan 	return ops->get_trng(dev, output, len);
132*434d6fd3SLin Jinhan }
133*434d6fd3SLin Jinhan 
134cc6ac5d6SJoseph Chen UCLASS_DRIVER(crypto) = {
135cc6ac5d6SJoseph Chen 	.id	= UCLASS_CRYPTO,
136cc6ac5d6SJoseph Chen 	.name	= "crypto",
137cc6ac5d6SJoseph Chen };
138