xref: /rk3399_rockchip-uboot/drivers/crypto/crypto-uclass.c (revision e15c98ee20b8dd02519a58e16b25e68be6e7b08a)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
4  */
5 
6 #include <crypto.h>
7 #include <keylad.h>
8 
9 static const u8 null_hash_sha1_value[] = {
10 	0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d,
11 	0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90,
12 	0xaf, 0xd8, 0x07, 0x09
13 };
14 
15 static const u8 null_hash_md5_value[] = {
16 	0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
17 	0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e
18 };
19 
20 static const u8 null_hash_sha256_value[] = {
21 	0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
22 	0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
23 	0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
24 	0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55
25 };
26 
27 static const u8 null_hash_sha512_value[] = {
28 	0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd,
29 	0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07,
30 	0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc,
31 	0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce,
32 	0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0,
33 	0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f,
34 	0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81,
35 	0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e
36 };
37 
38 const static u8 null_hash_sm3_value[] = {
39 	0x1a, 0xb2, 0x1d, 0x83, 0x55, 0xcf, 0xa1, 0x7f,
40 	0x8e, 0x61, 0x19, 0x48, 0x31, 0xe8, 0x1a, 0x8f,
41 	0x22, 0xbe, 0xc8, 0xc7, 0x28, 0xfe, 0xfb, 0x74,
42 	0x7e, 0xd0, 0x35, 0xeb, 0x50, 0x82, 0xaa, 0x2b
43 };
44 
45 u32 crypto_algo_nbits(u32 algo)
46 {
47 	switch (algo) {
48 	case CRYPTO_MD5:
49 	case CRYPTO_HMAC_MD5:
50 		return 128;
51 	case CRYPTO_SHA1:
52 	case CRYPTO_HMAC_SHA1:
53 		return 160;
54 	case CRYPTO_SHA256:
55 	case CRYPTO_HMAC_SHA256:
56 		return 256;
57 	case CRYPTO_SHA512:
58 	case CRYPTO_HMAC_SHA512:
59 		return 512;
60 	case CRYPTO_SM3:
61 	case CRYPTO_HMAC_SM3:
62 		return 256;
63 	case CRYPTO_RSA512:
64 		return 512;
65 	case CRYPTO_RSA1024:
66 		return 1024;
67 	case CRYPTO_RSA2048:
68 		return 2048;
69 	case CRYPTO_RSA3072:
70 		return 3072;
71 	case CRYPTO_RSA4096:
72 		return 4096;
73 	case CRYPTO_SM2:
74 		return 256;
75 	case CRYPTO_ECC_192R1:
76 		return 192;
77 	case CRYPTO_ECC_224R1:
78 		return 224;
79 	case CRYPTO_ECC_256R1:
80 		return 256;
81 	}
82 
83 	printf("Unknown crypto algorithm: 0x%x\n", algo);
84 
85 	return 0;
86 }
87 
88 struct udevice *crypto_get_device(u32 capability)
89 {
90 	const struct dm_crypto_ops *ops;
91 	struct udevice *dev;
92 	struct uclass *uc;
93 	int ret;
94 	u32 cap;
95 
96 	ret = uclass_get(UCLASS_CRYPTO, &uc);
97 	if (ret)
98 		return NULL;
99 
100 	for (uclass_first_device(UCLASS_CRYPTO, &dev);
101 	     dev;
102 	     uclass_next_device(&dev)) {
103 		ops = device_get_ops(dev);
104 		if (!ops || !ops->capability)
105 			continue;
106 
107 		cap = ops->capability(dev);
108 		if ((cap & capability) == capability)
109 			return dev;
110 	}
111 
112 	return NULL;
113 }
114 
115 int crypto_sha_init(struct udevice *dev, sha_context *ctx)
116 {
117 	const struct dm_crypto_ops *ops = device_get_ops(dev);
118 
119 	if (ctx && !ctx->length)
120 		return 0;
121 
122 	if (!ops || !ops->sha_init)
123 		return -ENOSYS;
124 
125 	return ops->sha_init(dev, ctx);
126 }
127 
128 int crypto_sha_update(struct udevice *dev, u32 *input, u32 len)
129 {
130 	const struct dm_crypto_ops *ops = device_get_ops(dev);
131 
132 	if (!len)
133 		return 0;
134 
135 	if (!ops || !ops->sha_update)
136 		return -ENOSYS;
137 
138 	return ops->sha_update(dev, input, len);
139 }
140 
141 int crypto_sha_final(struct udevice *dev, sha_context *ctx, u8 *output)
142 {
143 	const struct dm_crypto_ops *ops = device_get_ops(dev);
144 	const u8 *null_hash = NULL;
145 	u32 hash_size = 0;
146 
147 	if (ctx && !ctx->length && output) {
148 		switch (ctx->algo) {
149 		case CRYPTO_MD5:
150 			null_hash = null_hash_md5_value;
151 			hash_size = sizeof(null_hash_md5_value);
152 			break;
153 		case CRYPTO_SHA1:
154 			null_hash = null_hash_sha1_value;
155 			hash_size = sizeof(null_hash_sha1_value);
156 			break;
157 		case CRYPTO_SHA256:
158 			null_hash = null_hash_sha256_value;
159 			hash_size = sizeof(null_hash_sha256_value);
160 			break;
161 		case CRYPTO_SHA512:
162 			null_hash = null_hash_sha512_value;
163 			hash_size = sizeof(null_hash_sha512_value);
164 			break;
165 		case CRYPTO_SM3:
166 			null_hash = null_hash_sm3_value;
167 			hash_size = sizeof(null_hash_sm3_value);
168 			break;
169 		default:
170 			return -EINVAL;
171 		}
172 
173 		memcpy(output, null_hash, hash_size);
174 
175 		return 0;
176 	}
177 
178 	if (!ops || !ops->sha_final)
179 		return -ENOSYS;
180 
181 	return ops->sha_final(dev, ctx, output);
182 }
183 
184 int crypto_hmac_init(struct udevice *dev, sha_context *ctx,
185 		     u8 *key, u32 key_len)
186 {
187 	const struct dm_crypto_ops *ops = device_get_ops(dev);
188 
189 	if (ctx && !ctx->length)
190 		return -EINVAL;
191 
192 	if (!ops || !ops->hmac_init)
193 		return -ENOSYS;
194 
195 	return ops->hmac_init(dev, ctx, key, key_len);
196 }
197 
198 int crypto_hmac_update(struct udevice *dev, u32 *input, u32 len)
199 {
200 	const struct dm_crypto_ops *ops = device_get_ops(dev);
201 
202 	if (!len)
203 		return 0;
204 
205 	if (!ops || !ops->hmac_update)
206 		return -ENOSYS;
207 
208 	return ops->hmac_update(dev, input, len);
209 }
210 
211 int crypto_hmac_final(struct udevice *dev, sha_context *ctx, u8 *output)
212 {
213 	const struct dm_crypto_ops *ops = device_get_ops(dev);
214 
215 	if (!ops || !ops->hmac_final)
216 		return -ENOSYS;
217 
218 	return ops->hmac_final(dev, ctx, output);
219 }
220 
221 int crypto_sha_csum(struct udevice *dev, sha_context *ctx,
222 		    char *input, u32 input_len, u8 *output)
223 {
224 	int ret;
225 
226 	ret = crypto_sha_init(dev, ctx);
227 	if (ret)
228 		return ret;
229 
230 	ret = crypto_sha_update(dev, (u32 *)input, input_len);
231 	if (ret)
232 		return ret;
233 
234 	ret = crypto_sha_final(dev, ctx, output);
235 
236 	return ret;
237 }
238 
239 int crypto_sha_regions_csum(struct udevice *dev, sha_context *ctx,
240 			    const struct image_region region[],
241 			    int region_count, u8 *output)
242 {
243 	int i, ret;
244 
245 	ctx->length = 0;
246 	for (i = 0; i < region_count; i++)
247 		ctx->length += region[i].size;
248 
249 	ret = crypto_sha_init(dev, ctx);
250 	if (ret)
251 		return ret;
252 
253 	for (i = 0; i < region_count; i++) {
254 		ret = crypto_sha_update(dev, (void *)region[i].data,
255 					region[i].size);
256 		if (ret)
257 			return ret;
258 	}
259 
260 	return crypto_sha_final(dev, ctx, output);
261 }
262 
263 int crypto_rsa_verify(struct udevice *dev, rsa_key *ctx, u8 *sign, u8 *output)
264 {
265 	const struct dm_crypto_ops *ops = device_get_ops(dev);
266 
267 	if (!ops || !ops->rsa_verify)
268 		return -ENOSYS;
269 
270 	if (!ctx || !ctx->n || !ctx->e || !sign || !output)
271 		return -EINVAL;
272 
273 	return ops->rsa_verify(dev, ctx, sign, output);
274 }
275 
276 int crypto_ec_verify(struct udevice *dev, ec_key *ctx, u8 *hash, u32 hash_len, u8 *sign)
277 {
278 	const struct dm_crypto_ops *ops = device_get_ops(dev);
279 
280 	if (!ops || !ops->ec_verify)
281 		return -ENOSYS;
282 
283 	if (!ctx || !ctx->x || !ctx->y || !ctx->y || !hash || hash_len == 0 || !sign)
284 		return -EINVAL;
285 
286 	return ops->ec_verify(dev, ctx, hash, hash_len, sign);
287 }
288 
289 int crypto_cipher(struct udevice *dev, cipher_context *ctx,
290 		  const u8 *in, u8 *out, u32 len, bool enc)
291 {
292 	const struct dm_crypto_ops *ops = device_get_ops(dev);
293 
294 	if (!ops || !ops->cipher_crypt)
295 		return -ENOSYS;
296 
297 	if (!ctx || !ctx->key || ctx->key_len == 0)
298 		return -EINVAL;
299 
300 	return ops->cipher_crypt(dev, ctx, in, out, len, enc);
301 }
302 
303 int crypto_mac(struct udevice *dev, cipher_context *ctx,
304 	       const u8 *in, u32 len, u8 *tag)
305 {
306 	const struct dm_crypto_ops *ops = device_get_ops(dev);
307 
308 	if (!ops || !ops->cipher_mac)
309 		return -ENOSYS;
310 
311 	if (!ctx || !ctx->key || ctx->key_len == 0)
312 		return -EINVAL;
313 
314 	return ops->cipher_mac(dev, ctx, in, len, tag);
315 }
316 
317 int crypto_ae(struct udevice *dev, cipher_context *ctx,
318 	      const u8 *in, u32 len, const u8 *aad, u32 aad_len,
319 	      u8 *out, u8 *tag)
320 {
321 	const struct dm_crypto_ops *ops = device_get_ops(dev);
322 
323 	if (!ops || !ops->cipher_ae)
324 		return -ENOSYS;
325 
326 	if (!ctx || !ctx->key || ctx->key_len == 0)
327 		return -EINVAL;
328 
329 	return ops->cipher_ae(dev, ctx, in, len, aad, aad_len, out, tag);
330 }
331 
332 int crypto_fw_cipher(struct udevice *dev, cipher_fw_context *ctx,
333 		     const u8 *in, u8 *out, u32 len, bool enc)
334 {
335 	const struct dm_crypto_ops *ops = device_get_ops(dev);
336 	struct udevice *keylad_dev;
337 
338 	if (!ops || !ops->cipher_fw_crypt)
339 		return -ENOSYS;
340 
341 	keylad_dev = keylad_get_device();
342 	if (!keylad_dev) {
343 		printf("No keylad device found.\n");
344 		return -ENOSYS;
345 	}
346 
347 	if (keylad_transfer_fwkey(keylad_dev, crypto_keytable_addr(dev),
348 				  ctx->fw_keyid, ctx->key_len)) {
349 		printf("Failed to transfer key from keylad.\n");
350 		return -ENOSYS;
351 	}
352 
353 	return ops->cipher_fw_crypt(dev, ctx, in, out, len, enc);
354 }
355 
356 ulong crypto_keytable_addr(struct udevice *dev)
357 {
358 	const struct dm_crypto_ops *ops = device_get_ops(dev);
359 
360 	if (!ops || !ops->keytable_addr)
361 		return 0;
362 
363 	return ops->keytable_addr(dev);
364 }
365 
366 UCLASS_DRIVER(crypto) = {
367 	.id	= UCLASS_CRYPTO,
368 	.name	= "crypto",
369 };
370