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