xref: /rk3399_rockchip-uboot/drivers/crypto/crypto-uclass.c (revision c14e46abc4fe0414cea6b176d8cf7282ea8e179a)
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 <crypto.h>
7cc6ac5d6SJoseph Chen 
8cc6ac5d6SJoseph Chen u32 crypto_algo_nbits(u32 algo)
9cc6ac5d6SJoseph Chen {
10cc6ac5d6SJoseph Chen 	switch (algo) {
11cc6ac5d6SJoseph Chen 	case CRYPTO_MD5:
12cc6ac5d6SJoseph Chen 		return 128;
13cc6ac5d6SJoseph Chen 	case CRYPTO_SHA1:
14cc6ac5d6SJoseph Chen 		return 160;
15cc6ac5d6SJoseph Chen 	case CRYPTO_SHA256:
16cc6ac5d6SJoseph Chen 		return 256;
17e7846385SLin Jinhan 	case CRYPTO_SHA512:
18e7846385SLin Jinhan 		return 512;
19cc6ac5d6SJoseph Chen 	case CRYPTO_RSA512:
20cc6ac5d6SJoseph Chen 		return 512;
21cc6ac5d6SJoseph Chen 	case CRYPTO_RSA1024:
22cc6ac5d6SJoseph Chen 		return 1024;
23cc6ac5d6SJoseph Chen 	case CRYPTO_RSA2048:
24cc6ac5d6SJoseph Chen 		return 2048;
25b353a43cSLin Jinhan 	case CRYPTO_RSA3072:
26b353a43cSLin Jinhan 		return 3072;
27b353a43cSLin Jinhan 	case CRYPTO_RSA4096:
28b353a43cSLin Jinhan 		return 4096;
29cc6ac5d6SJoseph Chen 	}
30cc6ac5d6SJoseph Chen 
31cc6ac5d6SJoseph Chen 	printf("Unknown crypto algorithm: 0x%x\n", algo);
32cc6ac5d6SJoseph Chen 
33cc6ac5d6SJoseph Chen 	return 0;
34cc6ac5d6SJoseph Chen }
35cc6ac5d6SJoseph Chen 
36cc6ac5d6SJoseph Chen struct udevice *crypto_get_device(u32 capability)
37cc6ac5d6SJoseph Chen {
38cc6ac5d6SJoseph Chen 	const struct dm_crypto_ops *ops;
39cc6ac5d6SJoseph Chen 	struct udevice *dev;
40cc6ac5d6SJoseph Chen 	struct uclass *uc;
41cc6ac5d6SJoseph Chen 	int ret;
42cc6ac5d6SJoseph Chen 	u32 cap;
43cc6ac5d6SJoseph Chen 
44cc6ac5d6SJoseph Chen 	ret = uclass_get(UCLASS_CRYPTO, &uc);
45cc6ac5d6SJoseph Chen 	if (ret)
46cc6ac5d6SJoseph Chen 		return NULL;
47cc6ac5d6SJoseph Chen 
48cc6ac5d6SJoseph Chen 	for (uclass_first_device(UCLASS_CRYPTO, &dev);
49cc6ac5d6SJoseph Chen 	     dev;
50cc6ac5d6SJoseph Chen 	     uclass_next_device(&dev)) {
51cc6ac5d6SJoseph Chen 		ops = device_get_ops(dev);
52cc6ac5d6SJoseph Chen 		if (!ops || !ops->capability)
53cc6ac5d6SJoseph Chen 			continue;
54cc6ac5d6SJoseph Chen 
55cc6ac5d6SJoseph Chen 		cap = ops->capability(dev);
56cc6ac5d6SJoseph Chen 		if ((cap & capability) == capability)
57cc6ac5d6SJoseph Chen 			return dev;
58cc6ac5d6SJoseph Chen 	}
59cc6ac5d6SJoseph Chen 
60cc6ac5d6SJoseph Chen 	return NULL;
61cc6ac5d6SJoseph Chen }
62cc6ac5d6SJoseph Chen 
63cc6ac5d6SJoseph Chen int crypto_sha_init(struct udevice *dev, sha_context *ctx)
64cc6ac5d6SJoseph Chen {
65cc6ac5d6SJoseph Chen 	const struct dm_crypto_ops *ops = device_get_ops(dev);
66cc6ac5d6SJoseph Chen 
67cc6ac5d6SJoseph Chen 	if (!ops || !ops->sha_init)
68cc6ac5d6SJoseph Chen 		return -ENOSYS;
69cc6ac5d6SJoseph Chen 
70cc6ac5d6SJoseph Chen 	return ops->sha_init(dev, ctx);
71cc6ac5d6SJoseph Chen }
72cc6ac5d6SJoseph Chen 
73cc6ac5d6SJoseph Chen int crypto_sha_update(struct udevice *dev, u32 *input, u32 len)
74cc6ac5d6SJoseph Chen {
75cc6ac5d6SJoseph Chen 	const struct dm_crypto_ops *ops = device_get_ops(dev);
76cc6ac5d6SJoseph Chen 
77cc6ac5d6SJoseph Chen 	if (!ops || !ops->sha_update)
78cc6ac5d6SJoseph Chen 		return -ENOSYS;
79cc6ac5d6SJoseph Chen 
80cc6ac5d6SJoseph Chen 	return ops->sha_update(dev, input, len);
81cc6ac5d6SJoseph Chen }
82cc6ac5d6SJoseph Chen 
83cc6ac5d6SJoseph Chen int crypto_sha_final(struct udevice *dev, sha_context *ctx, u8 *output)
84cc6ac5d6SJoseph Chen {
85cc6ac5d6SJoseph Chen 	const struct dm_crypto_ops *ops = device_get_ops(dev);
86cc6ac5d6SJoseph Chen 
87cc6ac5d6SJoseph Chen 	if (!ops || !ops->sha_final)
88cc6ac5d6SJoseph Chen 		return -ENOSYS;
89cc6ac5d6SJoseph Chen 
90cc6ac5d6SJoseph Chen 	return ops->sha_final(dev, ctx, output);
91cc6ac5d6SJoseph Chen }
92cc6ac5d6SJoseph Chen 
93cc6ac5d6SJoseph Chen int crypto_sha_csum(struct udevice *dev, sha_context *ctx,
94cc6ac5d6SJoseph Chen 		    char *input, u32 input_len, u8 *output)
95cc6ac5d6SJoseph Chen {
96cc6ac5d6SJoseph Chen 	int ret;
97cc6ac5d6SJoseph Chen 
98cc6ac5d6SJoseph Chen 	ret = crypto_sha_init(dev, ctx);
99cc6ac5d6SJoseph Chen 	if (ret)
100cc6ac5d6SJoseph Chen 		return ret;
101cc6ac5d6SJoseph Chen 
102cc6ac5d6SJoseph Chen 	ret = crypto_sha_update(dev, (u32 *)input, input_len);
103cc6ac5d6SJoseph Chen 	if (ret)
104cc6ac5d6SJoseph Chen 		return ret;
105cc6ac5d6SJoseph Chen 
106cc6ac5d6SJoseph Chen 	ret = crypto_sha_final(dev, ctx, output);
107cc6ac5d6SJoseph Chen 
108cc6ac5d6SJoseph Chen 	return ret;
109cc6ac5d6SJoseph Chen }
110cc6ac5d6SJoseph Chen 
111*c14e46abSJoseph Chen int crypto_sha_regions_csum(struct udevice *dev, sha_context *ctx,
112*c14e46abSJoseph Chen 			    const struct image_region region[],
113*c14e46abSJoseph Chen 			    int region_count, u8 *output)
114*c14e46abSJoseph Chen {
115*c14e46abSJoseph Chen 	int i, ret;
116*c14e46abSJoseph Chen 
117*c14e46abSJoseph Chen 	ctx->length = 0;
118*c14e46abSJoseph Chen 	for (i = 0; i < region_count; i++)
119*c14e46abSJoseph Chen 		ctx->length += region[i].size;
120*c14e46abSJoseph Chen 
121*c14e46abSJoseph Chen 	ret = crypto_sha_init(dev, ctx);
122*c14e46abSJoseph Chen 	if (ret)
123*c14e46abSJoseph Chen 		return ret;
124*c14e46abSJoseph Chen 
125*c14e46abSJoseph Chen 	for (i = 0; i < region_count; i++) {
126*c14e46abSJoseph Chen 		ret = crypto_sha_update(dev, (void *)region[i].data,
127*c14e46abSJoseph Chen 					region[i].size);
128*c14e46abSJoseph Chen 		if (ret)
129*c14e46abSJoseph Chen 			return ret;
130*c14e46abSJoseph Chen 	}
131*c14e46abSJoseph Chen 
132*c14e46abSJoseph Chen 	return crypto_sha_final(dev, ctx, output);
133*c14e46abSJoseph Chen }
134*c14e46abSJoseph Chen 
135cc6ac5d6SJoseph Chen int crypto_rsa_verify(struct udevice *dev, rsa_key *ctx, u8 *sign, u8 *output)
136cc6ac5d6SJoseph Chen {
137cc6ac5d6SJoseph Chen 	const struct dm_crypto_ops *ops = device_get_ops(dev);
138cc6ac5d6SJoseph Chen 
139cc6ac5d6SJoseph Chen 	if (!ops || !ops->rsa_verify)
140cc6ac5d6SJoseph Chen 		return -ENOSYS;
141cc6ac5d6SJoseph Chen 
142cc6ac5d6SJoseph Chen 	return ops->rsa_verify(dev, ctx, sign, output);
143cc6ac5d6SJoseph Chen }
144cc6ac5d6SJoseph Chen 
145434d6fd3SLin Jinhan int crypto_get_trng(struct udevice *dev, u8 *output, u32 len)
146434d6fd3SLin Jinhan {
147434d6fd3SLin Jinhan 	const struct dm_crypto_ops *ops = device_get_ops(dev);
148434d6fd3SLin Jinhan 
149434d6fd3SLin Jinhan 	if (!ops || !ops->get_trng)
150434d6fd3SLin Jinhan 		return -ENOSYS;
151434d6fd3SLin Jinhan 
152434d6fd3SLin Jinhan 	return ops->get_trng(dev, output, len);
153434d6fd3SLin Jinhan }
154434d6fd3SLin Jinhan 
155cc6ac5d6SJoseph Chen UCLASS_DRIVER(crypto) = {
156cc6ac5d6SJoseph Chen 	.id	= UCLASS_CRYPTO,
157cc6ac5d6SJoseph Chen 	.name	= "crypto",
158cc6ac5d6SJoseph Chen };
159