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