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> 7*f400b2a4SLin 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 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 88cc6ac5d6SJoseph Chen struct udevice *crypto_get_device(u32 capability) 89cc6ac5d6SJoseph Chen { 90cc6ac5d6SJoseph Chen const struct dm_crypto_ops *ops; 91cc6ac5d6SJoseph Chen struct udevice *dev; 92cc6ac5d6SJoseph Chen struct uclass *uc; 93cc6ac5d6SJoseph Chen int ret; 94cc6ac5d6SJoseph Chen u32 cap; 95cc6ac5d6SJoseph Chen 96cc6ac5d6SJoseph Chen ret = uclass_get(UCLASS_CRYPTO, &uc); 97cc6ac5d6SJoseph Chen if (ret) 98cc6ac5d6SJoseph Chen return NULL; 99cc6ac5d6SJoseph Chen 100cc6ac5d6SJoseph Chen for (uclass_first_device(UCLASS_CRYPTO, &dev); 101cc6ac5d6SJoseph Chen dev; 102cc6ac5d6SJoseph Chen uclass_next_device(&dev)) { 103cc6ac5d6SJoseph Chen ops = device_get_ops(dev); 104cc6ac5d6SJoseph Chen if (!ops || !ops->capability) 105cc6ac5d6SJoseph Chen continue; 106cc6ac5d6SJoseph Chen 107cc6ac5d6SJoseph Chen cap = ops->capability(dev); 108cc6ac5d6SJoseph Chen if ((cap & capability) == capability) 109cc6ac5d6SJoseph Chen return dev; 110cc6ac5d6SJoseph Chen } 111cc6ac5d6SJoseph Chen 112cc6ac5d6SJoseph Chen return NULL; 113cc6ac5d6SJoseph Chen } 114cc6ac5d6SJoseph Chen 115cc6ac5d6SJoseph Chen int crypto_sha_init(struct udevice *dev, sha_context *ctx) 116cc6ac5d6SJoseph Chen { 117cc6ac5d6SJoseph Chen const struct dm_crypto_ops *ops = device_get_ops(dev); 118cc6ac5d6SJoseph Chen 1196b5b88bcSLin Jinhan if (ctx && !ctx->length) 1206b5b88bcSLin Jinhan return 0; 1216b5b88bcSLin Jinhan 122cc6ac5d6SJoseph Chen if (!ops || !ops->sha_init) 123cc6ac5d6SJoseph Chen return -ENOSYS; 124cc6ac5d6SJoseph Chen 125cc6ac5d6SJoseph Chen return ops->sha_init(dev, ctx); 126cc6ac5d6SJoseph Chen } 127cc6ac5d6SJoseph Chen 128cc6ac5d6SJoseph Chen int crypto_sha_update(struct udevice *dev, u32 *input, u32 len) 129cc6ac5d6SJoseph Chen { 130cc6ac5d6SJoseph Chen const struct dm_crypto_ops *ops = device_get_ops(dev); 131cc6ac5d6SJoseph Chen 1326b5b88bcSLin Jinhan if (!len) 1336b5b88bcSLin Jinhan return 0; 1346b5b88bcSLin Jinhan 135cc6ac5d6SJoseph Chen if (!ops || !ops->sha_update) 136cc6ac5d6SJoseph Chen return -ENOSYS; 137cc6ac5d6SJoseph Chen 138cc6ac5d6SJoseph Chen return ops->sha_update(dev, input, len); 139cc6ac5d6SJoseph Chen } 140cc6ac5d6SJoseph Chen 141cc6ac5d6SJoseph Chen int crypto_sha_final(struct udevice *dev, sha_context *ctx, u8 *output) 142cc6ac5d6SJoseph Chen { 143cc6ac5d6SJoseph Chen const struct dm_crypto_ops *ops = device_get_ops(dev); 1446b5b88bcSLin Jinhan const u8 *null_hash = NULL; 1456b5b88bcSLin Jinhan u32 hash_size = 0; 1466b5b88bcSLin Jinhan 1476b5b88bcSLin Jinhan if (ctx && !ctx->length && output) { 1486b5b88bcSLin Jinhan switch (ctx->algo) { 1496b5b88bcSLin Jinhan case CRYPTO_MD5: 1506b5b88bcSLin Jinhan null_hash = null_hash_md5_value; 1516b5b88bcSLin Jinhan hash_size = sizeof(null_hash_md5_value); 1526b5b88bcSLin Jinhan break; 1536b5b88bcSLin Jinhan case CRYPTO_SHA1: 1546b5b88bcSLin Jinhan null_hash = null_hash_sha1_value; 1556b5b88bcSLin Jinhan hash_size = sizeof(null_hash_sha1_value); 1566b5b88bcSLin Jinhan break; 1576b5b88bcSLin Jinhan case CRYPTO_SHA256: 1586b5b88bcSLin Jinhan null_hash = null_hash_sha256_value; 1596b5b88bcSLin Jinhan hash_size = sizeof(null_hash_sha256_value); 1606b5b88bcSLin Jinhan break; 1616b5b88bcSLin Jinhan case CRYPTO_SHA512: 1626b5b88bcSLin Jinhan null_hash = null_hash_sha512_value; 1636b5b88bcSLin Jinhan hash_size = sizeof(null_hash_sha512_value); 1646b5b88bcSLin Jinhan break; 16549a2135eSLin Jinhan case CRYPTO_SM3: 16649a2135eSLin Jinhan null_hash = null_hash_sm3_value; 16749a2135eSLin Jinhan hash_size = sizeof(null_hash_sm3_value); 16849a2135eSLin Jinhan break; 1696b5b88bcSLin Jinhan default: 1706b5b88bcSLin Jinhan return -EINVAL; 1716b5b88bcSLin Jinhan } 1726b5b88bcSLin Jinhan 1736b5b88bcSLin Jinhan memcpy(output, null_hash, hash_size); 1746b5b88bcSLin Jinhan 1756b5b88bcSLin Jinhan return 0; 1766b5b88bcSLin Jinhan } 177cc6ac5d6SJoseph Chen 178cc6ac5d6SJoseph Chen if (!ops || !ops->sha_final) 179cc6ac5d6SJoseph Chen return -ENOSYS; 180cc6ac5d6SJoseph Chen 181cc6ac5d6SJoseph Chen return ops->sha_final(dev, ctx, output); 182cc6ac5d6SJoseph Chen } 183cc6ac5d6SJoseph Chen 18449a2135eSLin Jinhan int crypto_hmac_init(struct udevice *dev, sha_context *ctx, 18549a2135eSLin Jinhan u8 *key, u32 key_len) 18649a2135eSLin Jinhan { 18749a2135eSLin Jinhan const struct dm_crypto_ops *ops = device_get_ops(dev); 18849a2135eSLin Jinhan 18949a2135eSLin Jinhan if (ctx && !ctx->length) 19049a2135eSLin Jinhan return -EINVAL; 19149a2135eSLin Jinhan 19249a2135eSLin Jinhan if (!ops || !ops->hmac_init) 19349a2135eSLin Jinhan return -ENOSYS; 19449a2135eSLin Jinhan 19549a2135eSLin Jinhan return ops->hmac_init(dev, ctx, key, key_len); 19649a2135eSLin Jinhan } 19749a2135eSLin Jinhan 19849a2135eSLin Jinhan int crypto_hmac_update(struct udevice *dev, u32 *input, u32 len) 19949a2135eSLin Jinhan { 20049a2135eSLin Jinhan const struct dm_crypto_ops *ops = device_get_ops(dev); 20149a2135eSLin Jinhan 20249a2135eSLin Jinhan if (!len) 20349a2135eSLin Jinhan return 0; 20449a2135eSLin Jinhan 20549a2135eSLin Jinhan if (!ops || !ops->hmac_update) 20649a2135eSLin Jinhan return -ENOSYS; 20749a2135eSLin Jinhan 20849a2135eSLin Jinhan return ops->hmac_update(dev, input, len); 20949a2135eSLin Jinhan } 21049a2135eSLin Jinhan 21149a2135eSLin Jinhan int crypto_hmac_final(struct udevice *dev, sha_context *ctx, u8 *output) 21249a2135eSLin Jinhan { 21349a2135eSLin Jinhan const struct dm_crypto_ops *ops = device_get_ops(dev); 21449a2135eSLin Jinhan 21549a2135eSLin Jinhan if (!ops || !ops->hmac_final) 21649a2135eSLin Jinhan return -ENOSYS; 21749a2135eSLin Jinhan 21849a2135eSLin Jinhan return ops->hmac_final(dev, ctx, output); 21949a2135eSLin Jinhan } 22049a2135eSLin Jinhan 221cc6ac5d6SJoseph Chen int crypto_sha_csum(struct udevice *dev, sha_context *ctx, 222cc6ac5d6SJoseph Chen char *input, u32 input_len, u8 *output) 223cc6ac5d6SJoseph Chen { 224cc6ac5d6SJoseph Chen int ret; 225cc6ac5d6SJoseph Chen 226cc6ac5d6SJoseph Chen ret = crypto_sha_init(dev, ctx); 227cc6ac5d6SJoseph Chen if (ret) 228cc6ac5d6SJoseph Chen return ret; 229cc6ac5d6SJoseph Chen 230cc6ac5d6SJoseph Chen ret = crypto_sha_update(dev, (u32 *)input, input_len); 231cc6ac5d6SJoseph Chen if (ret) 232cc6ac5d6SJoseph Chen return ret; 233cc6ac5d6SJoseph Chen 234cc6ac5d6SJoseph Chen ret = crypto_sha_final(dev, ctx, output); 235cc6ac5d6SJoseph Chen 236cc6ac5d6SJoseph Chen return ret; 237cc6ac5d6SJoseph Chen } 238cc6ac5d6SJoseph Chen 239c14e46abSJoseph Chen int crypto_sha_regions_csum(struct udevice *dev, sha_context *ctx, 240c14e46abSJoseph Chen const struct image_region region[], 241c14e46abSJoseph Chen int region_count, u8 *output) 242c14e46abSJoseph Chen { 243c14e46abSJoseph Chen int i, ret; 244c14e46abSJoseph Chen 245c14e46abSJoseph Chen ctx->length = 0; 246c14e46abSJoseph Chen for (i = 0; i < region_count; i++) 247c14e46abSJoseph Chen ctx->length += region[i].size; 248c14e46abSJoseph Chen 249c14e46abSJoseph Chen ret = crypto_sha_init(dev, ctx); 250c14e46abSJoseph Chen if (ret) 251c14e46abSJoseph Chen return ret; 252c14e46abSJoseph Chen 253c14e46abSJoseph Chen for (i = 0; i < region_count; i++) { 254c14e46abSJoseph Chen ret = crypto_sha_update(dev, (void *)region[i].data, 255c14e46abSJoseph Chen region[i].size); 256c14e46abSJoseph Chen if (ret) 257c14e46abSJoseph Chen return ret; 258c14e46abSJoseph Chen } 259c14e46abSJoseph Chen 260c14e46abSJoseph Chen return crypto_sha_final(dev, ctx, output); 261c14e46abSJoseph Chen } 262c14e46abSJoseph Chen 263cc6ac5d6SJoseph Chen int crypto_rsa_verify(struct udevice *dev, rsa_key *ctx, u8 *sign, u8 *output) 264cc6ac5d6SJoseph Chen { 265cc6ac5d6SJoseph Chen const struct dm_crypto_ops *ops = device_get_ops(dev); 266cc6ac5d6SJoseph Chen 267cc6ac5d6SJoseph Chen if (!ops || !ops->rsa_verify) 268cc6ac5d6SJoseph Chen return -ENOSYS; 269cc6ac5d6SJoseph Chen 270549a74f7SLin Jinhan if (!ctx || !ctx->n || !ctx->e || !sign || !output) 271549a74f7SLin Jinhan return -EINVAL; 272549a74f7SLin Jinhan 273cc6ac5d6SJoseph Chen return ops->rsa_verify(dev, ctx, sign, output); 274cc6ac5d6SJoseph Chen } 275cc6ac5d6SJoseph Chen 27602b4cf42SLin Jinhan int crypto_ec_verify(struct udevice *dev, ec_key *ctx, u8 *hash, u32 hash_len, u8 *sign) 27702b4cf42SLin Jinhan { 27802b4cf42SLin Jinhan const struct dm_crypto_ops *ops = device_get_ops(dev); 27902b4cf42SLin Jinhan 28002b4cf42SLin Jinhan if (!ops || !ops->ec_verify) 28102b4cf42SLin Jinhan return -ENOSYS; 28202b4cf42SLin Jinhan 28302b4cf42SLin Jinhan if (!ctx || !ctx->x || !ctx->y || !ctx->y || !hash || hash_len == 0 || !sign) 28402b4cf42SLin Jinhan return -EINVAL; 28502b4cf42SLin Jinhan 28602b4cf42SLin Jinhan return ops->ec_verify(dev, ctx, hash, hash_len, sign); 28702b4cf42SLin Jinhan } 28802b4cf42SLin Jinhan 28949a2135eSLin Jinhan int crypto_cipher(struct udevice *dev, cipher_context *ctx, 29049a2135eSLin Jinhan const u8 *in, u8 *out, u32 len, bool enc) 29149a2135eSLin Jinhan { 29249a2135eSLin Jinhan const struct dm_crypto_ops *ops = device_get_ops(dev); 29349a2135eSLin Jinhan 29449a2135eSLin Jinhan if (!ops || !ops->cipher_crypt) 29549a2135eSLin Jinhan return -ENOSYS; 29649a2135eSLin Jinhan 297*f400b2a4SLin Jinhan if (!ctx || !ctx->key || ctx->key_len == 0) 298*f400b2a4SLin Jinhan return -EINVAL; 299*f400b2a4SLin Jinhan 30049a2135eSLin Jinhan return ops->cipher_crypt(dev, ctx, in, out, len, enc); 30149a2135eSLin Jinhan } 30249a2135eSLin Jinhan 303d9332f1cSLin Jinhan int crypto_mac(struct udevice *dev, cipher_context *ctx, 304d9332f1cSLin Jinhan const u8 *in, u32 len, u8 *tag) 305d9332f1cSLin Jinhan { 306d9332f1cSLin Jinhan const struct dm_crypto_ops *ops = device_get_ops(dev); 307d9332f1cSLin Jinhan 308d9332f1cSLin Jinhan if (!ops || !ops->cipher_mac) 309d9332f1cSLin Jinhan return -ENOSYS; 310d9332f1cSLin Jinhan 311*f400b2a4SLin Jinhan if (!ctx || !ctx->key || ctx->key_len == 0) 312*f400b2a4SLin Jinhan return -EINVAL; 313*f400b2a4SLin Jinhan 314d9332f1cSLin Jinhan return ops->cipher_mac(dev, ctx, in, len, tag); 315d9332f1cSLin Jinhan } 316d9332f1cSLin Jinhan 317c3ce9937SLin Jinhan int crypto_ae(struct udevice *dev, cipher_context *ctx, 318c3ce9937SLin Jinhan const u8 *in, u32 len, const u8 *aad, u32 aad_len, 319c3ce9937SLin Jinhan u8 *out, u8 *tag) 320c3ce9937SLin Jinhan { 321c3ce9937SLin Jinhan const struct dm_crypto_ops *ops = device_get_ops(dev); 322c3ce9937SLin Jinhan 323c3ce9937SLin Jinhan if (!ops || !ops->cipher_ae) 324c3ce9937SLin Jinhan return -ENOSYS; 325c3ce9937SLin Jinhan 326*f400b2a4SLin Jinhan if (!ctx || !ctx->key || ctx->key_len == 0) 327*f400b2a4SLin Jinhan return -EINVAL; 328*f400b2a4SLin Jinhan 329c3ce9937SLin Jinhan return ops->cipher_ae(dev, ctx, in, len, aad, aad_len, out, tag); 330c3ce9937SLin Jinhan } 331c3ce9937SLin Jinhan 332*f400b2a4SLin Jinhan int crypto_fw_cipher(struct udevice *dev, cipher_fw_context *ctx, 333*f400b2a4SLin Jinhan const u8 *in, u8 *out, u32 len, bool enc) 334*f400b2a4SLin Jinhan { 335*f400b2a4SLin Jinhan const struct dm_crypto_ops *ops = device_get_ops(dev); 336*f400b2a4SLin Jinhan struct udevice *keylad_dev; 337*f400b2a4SLin Jinhan 338*f400b2a4SLin Jinhan if (!ops || !ops->cipher_fw_crypt) 339*f400b2a4SLin Jinhan return -ENOSYS; 340*f400b2a4SLin Jinhan 341*f400b2a4SLin Jinhan keylad_dev = keylad_get_device(); 342*f400b2a4SLin Jinhan if (!keylad_dev) { 343*f400b2a4SLin Jinhan printf("No keylad device found.\n"); 344*f400b2a4SLin Jinhan return -ENOSYS; 345*f400b2a4SLin Jinhan } 346*f400b2a4SLin Jinhan 347*f400b2a4SLin Jinhan if (keylad_transfer_fwkey(keylad_dev, crypto_keytable_addr(dev), 348*f400b2a4SLin Jinhan ctx->fw_keyid, ctx->key_len)) { 349*f400b2a4SLin Jinhan printf("Failed to transfer key from keylad.\n"); 350*f400b2a4SLin Jinhan return -ENOSYS; 351*f400b2a4SLin Jinhan } 352*f400b2a4SLin Jinhan 353*f400b2a4SLin Jinhan return ops->cipher_fw_crypt(dev, ctx, in, out, len, enc); 354*f400b2a4SLin Jinhan } 355*f400b2a4SLin Jinhan 356*f400b2a4SLin Jinhan ulong crypto_keytable_addr(struct udevice *dev) 357*f400b2a4SLin Jinhan { 358*f400b2a4SLin Jinhan const struct dm_crypto_ops *ops = device_get_ops(dev); 359*f400b2a4SLin Jinhan 360*f400b2a4SLin Jinhan if (!ops || !ops->keytable_addr) 361*f400b2a4SLin Jinhan return 0; 362*f400b2a4SLin Jinhan 363*f400b2a4SLin Jinhan return ops->keytable_addr(dev); 364*f400b2a4SLin Jinhan } 365*f400b2a4SLin Jinhan 366cc6ac5d6SJoseph Chen UCLASS_DRIVER(crypto) = { 367cc6ac5d6SJoseph Chen .id = UCLASS_CRYPTO, 368cc6ac5d6SJoseph Chen .name = "crypto", 369cc6ac5d6SJoseph Chen }; 370