xref: /rk3399_rockchip-uboot/drivers/crypto/crypto-uclass.c (revision b353a43c9e441e8665efd1cc47824714ad67ed3f)
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;
20cc6ac5d6SJoseph Chen 	case CRYPTO_RSA512:
21cc6ac5d6SJoseph Chen 		return 512;
22cc6ac5d6SJoseph Chen 	case CRYPTO_RSA1024:
23cc6ac5d6SJoseph Chen 		return 1024;
24cc6ac5d6SJoseph Chen 	case CRYPTO_RSA2048:
25cc6ac5d6SJoseph Chen 		return 2048;
26*b353a43cSLin Jinhan 	case CRYPTO_RSA3072:
27*b353a43cSLin Jinhan 		return 3072;
28*b353a43cSLin Jinhan 	case CRYPTO_RSA4096:
29*b353a43cSLin Jinhan 		return 4096;
30cc6ac5d6SJoseph Chen 	}
31cc6ac5d6SJoseph Chen 
32cc6ac5d6SJoseph Chen 	printf("Unknown crypto algorithm: 0x%x\n", algo);
33cc6ac5d6SJoseph Chen 
34cc6ac5d6SJoseph Chen 	return 0;
35cc6ac5d6SJoseph Chen }
36cc6ac5d6SJoseph Chen 
37cc6ac5d6SJoseph Chen struct udevice *crypto_get_device(u32 capability)
38cc6ac5d6SJoseph Chen {
39cc6ac5d6SJoseph Chen 	const struct dm_crypto_ops *ops;
40cc6ac5d6SJoseph Chen 	struct udevice *dev;
41cc6ac5d6SJoseph Chen 	struct uclass *uc;
42cc6ac5d6SJoseph Chen 	int ret;
43cc6ac5d6SJoseph Chen 	u32 cap;
44cc6ac5d6SJoseph Chen 
45cc6ac5d6SJoseph Chen 	ret = uclass_get(UCLASS_CRYPTO, &uc);
46cc6ac5d6SJoseph Chen 	if (ret)
47cc6ac5d6SJoseph Chen 		return NULL;
48cc6ac5d6SJoseph Chen 
49cc6ac5d6SJoseph Chen 	for (uclass_first_device(UCLASS_CRYPTO, &dev);
50cc6ac5d6SJoseph Chen 	     dev;
51cc6ac5d6SJoseph Chen 	     uclass_next_device(&dev)) {
52cc6ac5d6SJoseph Chen 		ops = device_get_ops(dev);
53cc6ac5d6SJoseph Chen 		if (!ops || !ops->capability)
54cc6ac5d6SJoseph Chen 			continue;
55cc6ac5d6SJoseph Chen 
56cc6ac5d6SJoseph Chen 		cap = ops->capability(dev);
57cc6ac5d6SJoseph Chen 		if ((cap & capability) == capability)
58cc6ac5d6SJoseph Chen 			return dev;
59cc6ac5d6SJoseph Chen 	}
60cc6ac5d6SJoseph Chen 
61cc6ac5d6SJoseph Chen 	return NULL;
62cc6ac5d6SJoseph Chen }
63cc6ac5d6SJoseph Chen 
64cc6ac5d6SJoseph Chen int crypto_sha_init(struct udevice *dev, sha_context *ctx)
65cc6ac5d6SJoseph Chen {
66cc6ac5d6SJoseph Chen 	const struct dm_crypto_ops *ops = device_get_ops(dev);
67cc6ac5d6SJoseph Chen 
68cc6ac5d6SJoseph Chen 	if (!ops || !ops->sha_init)
69cc6ac5d6SJoseph Chen 		return -ENOSYS;
70cc6ac5d6SJoseph Chen 
71cc6ac5d6SJoseph Chen 	return ops->sha_init(dev, ctx);
72cc6ac5d6SJoseph Chen }
73cc6ac5d6SJoseph Chen 
74cc6ac5d6SJoseph Chen int crypto_sha_update(struct udevice *dev, u32 *input, u32 len)
75cc6ac5d6SJoseph Chen {
76cc6ac5d6SJoseph Chen 	const struct dm_crypto_ops *ops = device_get_ops(dev);
77cc6ac5d6SJoseph Chen 
78cc6ac5d6SJoseph Chen 	if (!ops || !ops->sha_update)
79cc6ac5d6SJoseph Chen 		return -ENOSYS;
80cc6ac5d6SJoseph Chen 
81cc6ac5d6SJoseph Chen 	return ops->sha_update(dev, input, len);
82cc6ac5d6SJoseph Chen }
83cc6ac5d6SJoseph Chen 
84cc6ac5d6SJoseph Chen int crypto_sha_final(struct udevice *dev, sha_context *ctx, u8 *output)
85cc6ac5d6SJoseph Chen {
86cc6ac5d6SJoseph Chen 	const struct dm_crypto_ops *ops = device_get_ops(dev);
87cc6ac5d6SJoseph Chen 
88cc6ac5d6SJoseph Chen 	if (!ops || !ops->sha_final)
89cc6ac5d6SJoseph Chen 		return -ENOSYS;
90cc6ac5d6SJoseph Chen 
91cc6ac5d6SJoseph Chen 	return ops->sha_final(dev, ctx, output);
92cc6ac5d6SJoseph Chen }
93cc6ac5d6SJoseph Chen 
94cc6ac5d6SJoseph Chen int crypto_sha_csum(struct udevice *dev, sha_context *ctx,
95cc6ac5d6SJoseph Chen 		    char *input, u32 input_len, u8 *output)
96cc6ac5d6SJoseph Chen {
97cc6ac5d6SJoseph Chen 	int ret;
98cc6ac5d6SJoseph Chen 
99cc6ac5d6SJoseph Chen 	ret = crypto_sha_init(dev, ctx);
100cc6ac5d6SJoseph Chen 	if (ret)
101cc6ac5d6SJoseph Chen 		return ret;
102cc6ac5d6SJoseph Chen 
103cc6ac5d6SJoseph Chen 	ret = crypto_sha_update(dev, (u32 *)input, input_len);
104cc6ac5d6SJoseph Chen 	if (ret)
105cc6ac5d6SJoseph Chen 		return ret;
106cc6ac5d6SJoseph Chen 
107cc6ac5d6SJoseph Chen 	ret = crypto_sha_final(dev, ctx, output);
108cc6ac5d6SJoseph Chen 
109cc6ac5d6SJoseph Chen 	return ret;
110cc6ac5d6SJoseph Chen }
111cc6ac5d6SJoseph Chen 
112cc6ac5d6SJoseph Chen int crypto_rsa_verify(struct udevice *dev, rsa_key *ctx, u8 *sign, u8 *output)
113cc6ac5d6SJoseph Chen {
114cc6ac5d6SJoseph Chen 	const struct dm_crypto_ops *ops = device_get_ops(dev);
115cc6ac5d6SJoseph Chen 
116cc6ac5d6SJoseph Chen 	if (!ops || !ops->rsa_verify)
117cc6ac5d6SJoseph Chen 		return -ENOSYS;
118cc6ac5d6SJoseph Chen 
119cc6ac5d6SJoseph Chen 	return ops->rsa_verify(dev, ctx, sign, output);
120cc6ac5d6SJoseph Chen }
121cc6ac5d6SJoseph Chen 
122cc6ac5d6SJoseph Chen UCLASS_DRIVER(crypto) = {
123cc6ac5d6SJoseph Chen 	.id	= UCLASS_CRYPTO,
124cc6ac5d6SJoseph Chen 	.name	= "crypto",
125cc6ac5d6SJoseph Chen };
126