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