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