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