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