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 <crypto.h>
7f400b2a4SLin Jinhan #include <keylad.h>
8cc6ac5d6SJoseph Chen
96b5b88bcSLin Jinhan static const u8 null_hash_sha1_value[] = {
106b5b88bcSLin Jinhan 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d,
116b5b88bcSLin Jinhan 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90,
126b5b88bcSLin Jinhan 0xaf, 0xd8, 0x07, 0x09
136b5b88bcSLin Jinhan };
146b5b88bcSLin Jinhan
156b5b88bcSLin Jinhan static const u8 null_hash_md5_value[] = {
166b5b88bcSLin Jinhan 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
176b5b88bcSLin Jinhan 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e
186b5b88bcSLin Jinhan };
196b5b88bcSLin Jinhan
206b5b88bcSLin Jinhan static const u8 null_hash_sha256_value[] = {
216b5b88bcSLin Jinhan 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
226b5b88bcSLin Jinhan 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
236b5b88bcSLin Jinhan 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
246b5b88bcSLin Jinhan 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55
256b5b88bcSLin Jinhan };
266b5b88bcSLin Jinhan
276b5b88bcSLin Jinhan static const u8 null_hash_sha512_value[] = {
286b5b88bcSLin Jinhan 0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd,
296b5b88bcSLin Jinhan 0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07,
306b5b88bcSLin Jinhan 0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc,
316b5b88bcSLin Jinhan 0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce,
326b5b88bcSLin Jinhan 0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0,
336b5b88bcSLin Jinhan 0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f,
346b5b88bcSLin Jinhan 0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81,
356b5b88bcSLin Jinhan 0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e
366b5b88bcSLin Jinhan };
376b5b88bcSLin Jinhan
3849a2135eSLin Jinhan const static u8 null_hash_sm3_value[] = {
3949a2135eSLin Jinhan 0x1a, 0xb2, 0x1d, 0x83, 0x55, 0xcf, 0xa1, 0x7f,
4049a2135eSLin Jinhan 0x8e, 0x61, 0x19, 0x48, 0x31, 0xe8, 0x1a, 0x8f,
4149a2135eSLin Jinhan 0x22, 0xbe, 0xc8, 0xc7, 0x28, 0xfe, 0xfb, 0x74,
4249a2135eSLin Jinhan 0x7e, 0xd0, 0x35, 0xeb, 0x50, 0x82, 0xaa, 0x2b
4349a2135eSLin Jinhan };
4449a2135eSLin Jinhan
crypto_algo_nbits(u32 algo)45cc6ac5d6SJoseph Chen u32 crypto_algo_nbits(u32 algo)
46cc6ac5d6SJoseph Chen {
47cc6ac5d6SJoseph Chen switch (algo) {
48cc6ac5d6SJoseph Chen case CRYPTO_MD5:
4949a2135eSLin Jinhan case CRYPTO_HMAC_MD5:
50cc6ac5d6SJoseph Chen return 128;
51cc6ac5d6SJoseph Chen case CRYPTO_SHA1:
5249a2135eSLin Jinhan case CRYPTO_HMAC_SHA1:
53cc6ac5d6SJoseph Chen return 160;
54cc6ac5d6SJoseph Chen case CRYPTO_SHA256:
5549a2135eSLin Jinhan case CRYPTO_HMAC_SHA256:
56cc6ac5d6SJoseph Chen return 256;
57e7846385SLin Jinhan case CRYPTO_SHA512:
5849a2135eSLin Jinhan case CRYPTO_HMAC_SHA512:
59e7846385SLin Jinhan return 512;
6049a2135eSLin Jinhan case CRYPTO_SM3:
6149a2135eSLin Jinhan case CRYPTO_HMAC_SM3:
6249a2135eSLin Jinhan return 256;
63cc6ac5d6SJoseph Chen case CRYPTO_RSA512:
64cc6ac5d6SJoseph Chen return 512;
65cc6ac5d6SJoseph Chen case CRYPTO_RSA1024:
66cc6ac5d6SJoseph Chen return 1024;
67cc6ac5d6SJoseph Chen case CRYPTO_RSA2048:
68cc6ac5d6SJoseph Chen return 2048;
69b353a43cSLin Jinhan case CRYPTO_RSA3072:
70b353a43cSLin Jinhan return 3072;
71b353a43cSLin Jinhan case CRYPTO_RSA4096:
72b353a43cSLin Jinhan return 4096;
7302b4cf42SLin Jinhan case CRYPTO_SM2:
7402b4cf42SLin Jinhan return 256;
7502b4cf42SLin Jinhan case CRYPTO_ECC_192R1:
7602b4cf42SLin Jinhan return 192;
7702b4cf42SLin Jinhan case CRYPTO_ECC_224R1:
7802b4cf42SLin Jinhan return 224;
7902b4cf42SLin Jinhan case CRYPTO_ECC_256R1:
8002b4cf42SLin Jinhan return 256;
81cc6ac5d6SJoseph Chen }
82cc6ac5d6SJoseph Chen
83cc6ac5d6SJoseph Chen printf("Unknown crypto algorithm: 0x%x\n", algo);
84cc6ac5d6SJoseph Chen
85cc6ac5d6SJoseph Chen return 0;
86cc6ac5d6SJoseph Chen }
87cc6ac5d6SJoseph Chen
crypto_get_device(u32 capability)88cc6ac5d6SJoseph Chen struct udevice *crypto_get_device(u32 capability)
89cc6ac5d6SJoseph Chen {
9036e17db4Stroy.lin bool preferred_secure = false;
9136e17db4Stroy.lin bool cur_secure = false;
92cc6ac5d6SJoseph Chen const struct dm_crypto_ops *ops;
9336e17db4Stroy.lin struct udevice *best_fit_dev = NULL;
94cc6ac5d6SJoseph Chen struct udevice *dev;
95cc6ac5d6SJoseph Chen struct uclass *uc;
96cc6ac5d6SJoseph Chen int ret;
97cc6ac5d6SJoseph Chen u32 cap;
98cc6ac5d6SJoseph Chen
9936e17db4Stroy.lin #if defined(CONFIG_SPL_BUILD)
10036e17db4Stroy.lin preferred_secure = true;
10136e17db4Stroy.lin #else
10236e17db4Stroy.lin preferred_secure = false;
10336e17db4Stroy.lin #endif
10436e17db4Stroy.lin
105cc6ac5d6SJoseph Chen ret = uclass_get(UCLASS_CRYPTO, &uc);
106cc6ac5d6SJoseph Chen if (ret)
107cc6ac5d6SJoseph Chen return NULL;
108cc6ac5d6SJoseph Chen
109cc6ac5d6SJoseph Chen for (uclass_first_device(UCLASS_CRYPTO, &dev);
110cc6ac5d6SJoseph Chen dev;
111cc6ac5d6SJoseph Chen uclass_next_device(&dev)) {
112cc6ac5d6SJoseph Chen ops = device_get_ops(dev);
113cc6ac5d6SJoseph Chen if (!ops || !ops->capability)
114cc6ac5d6SJoseph Chen continue;
115cc6ac5d6SJoseph Chen
11636e17db4Stroy.lin cur_secure = ops->is_secure ? ops->is_secure(dev) : false;
11736e17db4Stroy.lin
118cc6ac5d6SJoseph Chen cap = ops->capability(dev);
11936e17db4Stroy.lin if ((cap & capability) == capability) {
12036e17db4Stroy.lin if (!best_fit_dev) {
12136e17db4Stroy.lin best_fit_dev = dev;
12236e17db4Stroy.lin continue;
123cc6ac5d6SJoseph Chen }
124cc6ac5d6SJoseph Chen
12536e17db4Stroy.lin if (preferred_secure == cur_secure)
12636e17db4Stroy.lin best_fit_dev = dev;
12736e17db4Stroy.lin }
12836e17db4Stroy.lin }
12936e17db4Stroy.lin
13036e17db4Stroy.lin return best_fit_dev;
131cc6ac5d6SJoseph Chen }
132cc6ac5d6SJoseph Chen
crypto_sha_init(struct udevice * dev,sha_context * ctx)133cc6ac5d6SJoseph Chen int crypto_sha_init(struct udevice *dev, sha_context *ctx)
134cc6ac5d6SJoseph Chen {
135cc6ac5d6SJoseph Chen const struct dm_crypto_ops *ops = device_get_ops(dev);
136cc6ac5d6SJoseph Chen
1376b5b88bcSLin Jinhan if (ctx && !ctx->length)
1386b5b88bcSLin Jinhan return 0;
1396b5b88bcSLin Jinhan
140cc6ac5d6SJoseph Chen if (!ops || !ops->sha_init)
141cc6ac5d6SJoseph Chen return -ENOSYS;
142cc6ac5d6SJoseph Chen
143cc6ac5d6SJoseph Chen return ops->sha_init(dev, ctx);
144cc6ac5d6SJoseph Chen }
145cc6ac5d6SJoseph Chen
crypto_sha_update(struct udevice * dev,u32 * input,u32 len)146cc6ac5d6SJoseph Chen int crypto_sha_update(struct udevice *dev, u32 *input, u32 len)
147cc6ac5d6SJoseph Chen {
148cc6ac5d6SJoseph Chen const struct dm_crypto_ops *ops = device_get_ops(dev);
149cc6ac5d6SJoseph Chen
1506b5b88bcSLin Jinhan if (!len)
1516b5b88bcSLin Jinhan return 0;
1526b5b88bcSLin Jinhan
153cc6ac5d6SJoseph Chen if (!ops || !ops->sha_update)
154cc6ac5d6SJoseph Chen return -ENOSYS;
155cc6ac5d6SJoseph Chen
156cc6ac5d6SJoseph Chen return ops->sha_update(dev, input, len);
157cc6ac5d6SJoseph Chen }
158cc6ac5d6SJoseph Chen
crypto_sha_final(struct udevice * dev,sha_context * ctx,u8 * output)159cc6ac5d6SJoseph Chen int crypto_sha_final(struct udevice *dev, sha_context *ctx, u8 *output)
160cc6ac5d6SJoseph Chen {
161cc6ac5d6SJoseph Chen const struct dm_crypto_ops *ops = device_get_ops(dev);
1626b5b88bcSLin Jinhan const u8 *null_hash = NULL;
1636b5b88bcSLin Jinhan u32 hash_size = 0;
1646b5b88bcSLin Jinhan
1656b5b88bcSLin Jinhan if (ctx && !ctx->length && output) {
1666b5b88bcSLin Jinhan switch (ctx->algo) {
1676b5b88bcSLin Jinhan case CRYPTO_MD5:
1686b5b88bcSLin Jinhan null_hash = null_hash_md5_value;
1696b5b88bcSLin Jinhan hash_size = sizeof(null_hash_md5_value);
1706b5b88bcSLin Jinhan break;
1716b5b88bcSLin Jinhan case CRYPTO_SHA1:
1726b5b88bcSLin Jinhan null_hash = null_hash_sha1_value;
1736b5b88bcSLin Jinhan hash_size = sizeof(null_hash_sha1_value);
1746b5b88bcSLin Jinhan break;
1756b5b88bcSLin Jinhan case CRYPTO_SHA256:
1766b5b88bcSLin Jinhan null_hash = null_hash_sha256_value;
1776b5b88bcSLin Jinhan hash_size = sizeof(null_hash_sha256_value);
1786b5b88bcSLin Jinhan break;
1796b5b88bcSLin Jinhan case CRYPTO_SHA512:
1806b5b88bcSLin Jinhan null_hash = null_hash_sha512_value;
1816b5b88bcSLin Jinhan hash_size = sizeof(null_hash_sha512_value);
1826b5b88bcSLin Jinhan break;
18349a2135eSLin Jinhan case CRYPTO_SM3:
18449a2135eSLin Jinhan null_hash = null_hash_sm3_value;
18549a2135eSLin Jinhan hash_size = sizeof(null_hash_sm3_value);
18649a2135eSLin Jinhan break;
1876b5b88bcSLin Jinhan default:
1886b5b88bcSLin Jinhan return -EINVAL;
1896b5b88bcSLin Jinhan }
1906b5b88bcSLin Jinhan
1916b5b88bcSLin Jinhan memcpy(output, null_hash, hash_size);
1926b5b88bcSLin Jinhan
1936b5b88bcSLin Jinhan return 0;
1946b5b88bcSLin Jinhan }
195cc6ac5d6SJoseph Chen
196cc6ac5d6SJoseph Chen if (!ops || !ops->sha_final)
197cc6ac5d6SJoseph Chen return -ENOSYS;
198cc6ac5d6SJoseph Chen
199cc6ac5d6SJoseph Chen return ops->sha_final(dev, ctx, output);
200cc6ac5d6SJoseph Chen }
201cc6ac5d6SJoseph Chen
crypto_hmac_init(struct udevice * dev,sha_context * ctx,u8 * key,u32 key_len)20249a2135eSLin Jinhan int crypto_hmac_init(struct udevice *dev, sha_context *ctx,
20349a2135eSLin Jinhan u8 *key, u32 key_len)
20449a2135eSLin Jinhan {
20549a2135eSLin Jinhan const struct dm_crypto_ops *ops = device_get_ops(dev);
20649a2135eSLin Jinhan
20749a2135eSLin Jinhan if (ctx && !ctx->length)
20849a2135eSLin Jinhan return -EINVAL;
20949a2135eSLin Jinhan
21049a2135eSLin Jinhan if (!ops || !ops->hmac_init)
21149a2135eSLin Jinhan return -ENOSYS;
21249a2135eSLin Jinhan
21349a2135eSLin Jinhan return ops->hmac_init(dev, ctx, key, key_len);
21449a2135eSLin Jinhan }
21549a2135eSLin Jinhan
crypto_hmac_update(struct udevice * dev,u32 * input,u32 len)21649a2135eSLin Jinhan int crypto_hmac_update(struct udevice *dev, u32 *input, u32 len)
21749a2135eSLin Jinhan {
21849a2135eSLin Jinhan const struct dm_crypto_ops *ops = device_get_ops(dev);
21949a2135eSLin Jinhan
22049a2135eSLin Jinhan if (!len)
22149a2135eSLin Jinhan return 0;
22249a2135eSLin Jinhan
22349a2135eSLin Jinhan if (!ops || !ops->hmac_update)
22449a2135eSLin Jinhan return -ENOSYS;
22549a2135eSLin Jinhan
22649a2135eSLin Jinhan return ops->hmac_update(dev, input, len);
22749a2135eSLin Jinhan }
22849a2135eSLin Jinhan
crypto_hmac_final(struct udevice * dev,sha_context * ctx,u8 * output)22949a2135eSLin Jinhan int crypto_hmac_final(struct udevice *dev, sha_context *ctx, u8 *output)
23049a2135eSLin Jinhan {
23149a2135eSLin Jinhan const struct dm_crypto_ops *ops = device_get_ops(dev);
23249a2135eSLin Jinhan
23349a2135eSLin Jinhan if (!ops || !ops->hmac_final)
23449a2135eSLin Jinhan return -ENOSYS;
23549a2135eSLin Jinhan
23649a2135eSLin Jinhan return ops->hmac_final(dev, ctx, output);
23749a2135eSLin Jinhan }
23849a2135eSLin Jinhan
crypto_sha_csum(struct udevice * dev,sha_context * ctx,char * input,u32 input_len,u8 * output)239cc6ac5d6SJoseph Chen int crypto_sha_csum(struct udevice *dev, sha_context *ctx,
240cc6ac5d6SJoseph Chen char *input, u32 input_len, u8 *output)
241cc6ac5d6SJoseph Chen {
242cc6ac5d6SJoseph Chen int ret;
243cc6ac5d6SJoseph Chen
244cc6ac5d6SJoseph Chen ret = crypto_sha_init(dev, ctx);
245cc6ac5d6SJoseph Chen if (ret)
246cc6ac5d6SJoseph Chen return ret;
247cc6ac5d6SJoseph Chen
248cc6ac5d6SJoseph Chen ret = crypto_sha_update(dev, (u32 *)input, input_len);
249cc6ac5d6SJoseph Chen if (ret)
250cc6ac5d6SJoseph Chen return ret;
251cc6ac5d6SJoseph Chen
252cc6ac5d6SJoseph Chen ret = crypto_sha_final(dev, ctx, output);
253cc6ac5d6SJoseph Chen
254cc6ac5d6SJoseph Chen return ret;
255cc6ac5d6SJoseph Chen }
256cc6ac5d6SJoseph Chen
crypto_sha_regions_csum(struct udevice * dev,sha_context * ctx,const struct image_region region[],int region_count,u8 * output)257c14e46abSJoseph Chen int crypto_sha_regions_csum(struct udevice *dev, sha_context *ctx,
258c14e46abSJoseph Chen const struct image_region region[],
259c14e46abSJoseph Chen int region_count, u8 *output)
260c14e46abSJoseph Chen {
261c14e46abSJoseph Chen int i, ret;
262c14e46abSJoseph Chen
263c14e46abSJoseph Chen ctx->length = 0;
264c14e46abSJoseph Chen for (i = 0; i < region_count; i++)
265c14e46abSJoseph Chen ctx->length += region[i].size;
266c14e46abSJoseph Chen
267c14e46abSJoseph Chen ret = crypto_sha_init(dev, ctx);
268c14e46abSJoseph Chen if (ret)
269c14e46abSJoseph Chen return ret;
270c14e46abSJoseph Chen
271c14e46abSJoseph Chen for (i = 0; i < region_count; i++) {
272c14e46abSJoseph Chen ret = crypto_sha_update(dev, (void *)region[i].data,
273c14e46abSJoseph Chen region[i].size);
274c14e46abSJoseph Chen if (ret)
275c14e46abSJoseph Chen return ret;
276c14e46abSJoseph Chen }
277c14e46abSJoseph Chen
278c14e46abSJoseph Chen return crypto_sha_final(dev, ctx, output);
279c14e46abSJoseph Chen }
280c14e46abSJoseph Chen
crypto_rsa_verify(struct udevice * dev,rsa_key * ctx,u8 * sign,u8 * output)281cc6ac5d6SJoseph Chen int crypto_rsa_verify(struct udevice *dev, rsa_key *ctx, u8 *sign, u8 *output)
282cc6ac5d6SJoseph Chen {
283cc6ac5d6SJoseph Chen const struct dm_crypto_ops *ops = device_get_ops(dev);
284cc6ac5d6SJoseph Chen
285cc6ac5d6SJoseph Chen if (!ops || !ops->rsa_verify)
286cc6ac5d6SJoseph Chen return -ENOSYS;
287cc6ac5d6SJoseph Chen
288549a74f7SLin Jinhan if (!ctx || !ctx->n || !ctx->e || !sign || !output)
289549a74f7SLin Jinhan return -EINVAL;
290549a74f7SLin Jinhan
291cc6ac5d6SJoseph Chen return ops->rsa_verify(dev, ctx, sign, output);
292cc6ac5d6SJoseph Chen }
293cc6ac5d6SJoseph Chen
crypto_ec_verify(struct udevice * dev,ec_key * ctx,u8 * hash,u32 hash_len,u8 * sign)29402b4cf42SLin Jinhan int crypto_ec_verify(struct udevice *dev, ec_key *ctx, u8 *hash, u32 hash_len, u8 *sign)
29502b4cf42SLin Jinhan {
29602b4cf42SLin Jinhan const struct dm_crypto_ops *ops = device_get_ops(dev);
29702b4cf42SLin Jinhan
29802b4cf42SLin Jinhan if (!ops || !ops->ec_verify)
29902b4cf42SLin Jinhan return -ENOSYS;
30002b4cf42SLin Jinhan
30102b4cf42SLin Jinhan if (!ctx || !ctx->x || !ctx->y || !ctx->y || !hash || hash_len == 0 || !sign)
30202b4cf42SLin Jinhan return -EINVAL;
30302b4cf42SLin Jinhan
30402b4cf42SLin Jinhan return ops->ec_verify(dev, ctx, hash, hash_len, sign);
30502b4cf42SLin Jinhan }
30602b4cf42SLin Jinhan
crypto_cipher(struct udevice * dev,cipher_context * ctx,const u8 * in,u8 * out,u32 len,bool enc)30749a2135eSLin Jinhan int crypto_cipher(struct udevice *dev, cipher_context *ctx,
30849a2135eSLin Jinhan const u8 *in, u8 *out, u32 len, bool enc)
30949a2135eSLin Jinhan {
31049a2135eSLin Jinhan const struct dm_crypto_ops *ops = device_get_ops(dev);
31149a2135eSLin Jinhan
31249a2135eSLin Jinhan if (!ops || !ops->cipher_crypt)
31349a2135eSLin Jinhan return -ENOSYS;
31449a2135eSLin Jinhan
315f400b2a4SLin Jinhan if (!ctx || !ctx->key || ctx->key_len == 0)
316f400b2a4SLin Jinhan return -EINVAL;
317f400b2a4SLin Jinhan
31849a2135eSLin Jinhan return ops->cipher_crypt(dev, ctx, in, out, len, enc);
31949a2135eSLin Jinhan }
32049a2135eSLin Jinhan
crypto_mac(struct udevice * dev,cipher_context * ctx,const u8 * in,u32 len,u8 * tag)321d9332f1cSLin Jinhan int crypto_mac(struct udevice *dev, cipher_context *ctx,
322d9332f1cSLin Jinhan const u8 *in, u32 len, u8 *tag)
323d9332f1cSLin Jinhan {
324d9332f1cSLin Jinhan const struct dm_crypto_ops *ops = device_get_ops(dev);
325d9332f1cSLin Jinhan
326d9332f1cSLin Jinhan if (!ops || !ops->cipher_mac)
327d9332f1cSLin Jinhan return -ENOSYS;
328d9332f1cSLin Jinhan
329f400b2a4SLin Jinhan if (!ctx || !ctx->key || ctx->key_len == 0)
330f400b2a4SLin Jinhan return -EINVAL;
331f400b2a4SLin Jinhan
332d9332f1cSLin Jinhan return ops->cipher_mac(dev, ctx, in, len, tag);
333d9332f1cSLin Jinhan }
334d9332f1cSLin Jinhan
crypto_ae(struct udevice * dev,cipher_context * ctx,const u8 * in,u32 len,const u8 * aad,u32 aad_len,u8 * out,u8 * tag)335c3ce9937SLin Jinhan int crypto_ae(struct udevice *dev, cipher_context *ctx,
336c3ce9937SLin Jinhan const u8 *in, u32 len, const u8 *aad, u32 aad_len,
337c3ce9937SLin Jinhan u8 *out, u8 *tag)
338c3ce9937SLin Jinhan {
339c3ce9937SLin Jinhan const struct dm_crypto_ops *ops = device_get_ops(dev);
340c3ce9937SLin Jinhan
341c3ce9937SLin Jinhan if (!ops || !ops->cipher_ae)
342c3ce9937SLin Jinhan return -ENOSYS;
343c3ce9937SLin Jinhan
344f400b2a4SLin Jinhan if (!ctx || !ctx->key || ctx->key_len == 0)
345f400b2a4SLin Jinhan return -EINVAL;
346f400b2a4SLin Jinhan
347c3ce9937SLin Jinhan return ops->cipher_ae(dev, ctx, in, len, aad, aad_len, out, tag);
348c3ce9937SLin Jinhan }
349c3ce9937SLin Jinhan
crypto_fw_cipher(struct udevice * dev,cipher_fw_context * ctx,const u8 * in,u8 * out,u32 len,bool enc)350f400b2a4SLin Jinhan int crypto_fw_cipher(struct udevice *dev, cipher_fw_context *ctx,
351f400b2a4SLin Jinhan const u8 *in, u8 *out, u32 len, bool enc)
352f400b2a4SLin Jinhan {
353*24a57c1cSLin Jinhan #if CONFIG_IS_ENABLED(DM_KEYLAD)
354f400b2a4SLin Jinhan const struct dm_crypto_ops *ops = device_get_ops(dev);
355f400b2a4SLin Jinhan struct udevice *keylad_dev;
356f400b2a4SLin Jinhan
357f400b2a4SLin Jinhan if (!ops || !ops->cipher_fw_crypt)
358f400b2a4SLin Jinhan return -ENOSYS;
359f400b2a4SLin Jinhan
36036e17db4Stroy.lin if (!ops->is_secure || !ops->is_secure(dev)) {
36136e17db4Stroy.lin printf("Only secure crypto support fwkey cipher.\n");
36236e17db4Stroy.lin return -ENOSYS;
36336e17db4Stroy.lin }
36436e17db4Stroy.lin
365f400b2a4SLin Jinhan keylad_dev = keylad_get_device();
366f400b2a4SLin Jinhan if (!keylad_dev) {
367f400b2a4SLin Jinhan printf("No keylad device found.\n");
368f400b2a4SLin Jinhan return -ENOSYS;
369f400b2a4SLin Jinhan }
370f400b2a4SLin Jinhan
371f400b2a4SLin Jinhan if (keylad_transfer_fwkey(keylad_dev, crypto_keytable_addr(dev),
372f400b2a4SLin Jinhan ctx->fw_keyid, ctx->key_len)) {
373f400b2a4SLin Jinhan printf("Failed to transfer key from keylad.\n");
374f400b2a4SLin Jinhan return -ENOSYS;
375f400b2a4SLin Jinhan }
376f400b2a4SLin Jinhan
377f400b2a4SLin Jinhan return ops->cipher_fw_crypt(dev, ctx, in, out, len, enc);
378*24a57c1cSLin Jinhan #else
379*24a57c1cSLin Jinhan return -ENOSYS;
380*24a57c1cSLin Jinhan #endif
381f400b2a4SLin Jinhan }
382f400b2a4SLin Jinhan
crypto_keytable_addr(struct udevice * dev)383f400b2a4SLin Jinhan ulong crypto_keytable_addr(struct udevice *dev)
384f400b2a4SLin Jinhan {
385f400b2a4SLin Jinhan const struct dm_crypto_ops *ops = device_get_ops(dev);
386f400b2a4SLin Jinhan
387f400b2a4SLin Jinhan if (!ops || !ops->keytable_addr)
388f400b2a4SLin Jinhan return 0;
389f400b2a4SLin Jinhan
390f400b2a4SLin Jinhan return ops->keytable_addr(dev);
391f400b2a4SLin Jinhan }
392f400b2a4SLin Jinhan
crypto_is_secure(struct udevice * dev)39336e17db4Stroy.lin bool crypto_is_secure(struct udevice *dev)
39436e17db4Stroy.lin {
39536e17db4Stroy.lin const struct dm_crypto_ops *ops = device_get_ops(dev);
39636e17db4Stroy.lin
39736e17db4Stroy.lin if (!ops || !ops->is_secure)
39836e17db4Stroy.lin return false;
39936e17db4Stroy.lin
40036e17db4Stroy.lin return ops->is_secure(dev);
40136e17db4Stroy.lin }
40236e17db4Stroy.lin
403cc6ac5d6SJoseph Chen UCLASS_DRIVER(crypto) = {
404cc6ac5d6SJoseph Chen .id = UCLASS_CRYPTO,
405cc6ac5d6SJoseph Chen .name = "crypto",
406cc6ac5d6SJoseph Chen };
407