1/* 2 * Copyright (C) 2022-2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "rand.h" 17 18#include <limits.h> 19#include <securec.h> 20#include "rand_spi.h" 21#ifdef CRYPTO_MBEDTLS 22#include "mbedtls_rand.h" 23#else 24#include "rand_openssl.h" 25#endif 26#include "log.h" 27#include "config.h" 28#include "memory.h" 29#include "utils.h" 30 31typedef HcfResult (*HcfRandSpiCreateFunc)(HcfRandSpi **); 32 33typedef struct { 34 HcfRand base; 35 36 HcfRandSpi *spiObj; 37 38 const char *algoName; 39} HcfRandImpl; 40 41typedef struct { 42 char *algoName; 43 44 HcfRandSpiCreateFunc createSpiFunc; 45} HcfRandAbility; 46 47static const char *GetRandClass(void) 48{ 49 return "Rand"; 50} 51 52static const HcfRandAbility RAND_ABILITY_SET[] = { 53#ifdef CRYPTO_MBEDTLS 54 { "MbedtlsRand", MbedtlsRandSpiCreate } 55#else 56 { "OpensslRand", HcfRandSpiCreate } 57#endif 58}; 59 60static HcfRandSpiCreateFunc FindAbility(const char *algoName) 61{ 62 for (uint32_t i = 0; i < (sizeof(RAND_ABILITY_SET) / sizeof(RAND_ABILITY_SET[0])); i++) { 63 if (strcmp(RAND_ABILITY_SET[i].algoName, algoName) == 0) { 64 return RAND_ABILITY_SET[i].createSpiFunc; 65 } 66 } 67 LOGE("Algo not support! [Algo]: %s", algoName); 68 return NULL; 69} 70 71static HcfResult GenerateRandom(HcfRand *self, int32_t numBytes, HcfBlob *random) 72{ 73 if ((self == NULL) || (random == NULL)) { 74 LOGE("Invalid params!"); 75 return HCF_INVALID_PARAMS; 76 } 77 if (numBytes <= 0) { 78 LOGE("Invalid numBytes!"); 79 return HCF_INVALID_PARAMS; 80 } 81 if (!HcfIsClassMatch((HcfObjectBase *)self, GetRandClass())) { 82 LOGE("Class is not match."); 83 return HCF_INVALID_PARAMS; 84 } 85 return ((HcfRandImpl *)self)->spiObj->engineGenerateRandom( 86 ((HcfRandImpl *)self)->spiObj, numBytes, random); 87} 88 89static const char *GetAlgoName(HcfRand *self) 90{ 91 if (self == NULL) { 92 LOGE("The input self ptr is NULL!"); 93 return NULL; 94 } 95 if (!HcfIsClassMatch((HcfObjectBase *)self, GetRandClass())) { 96 LOGE("Class is not match!"); 97 return NULL; 98 } 99 return ((HcfRandImpl *)self)->spiObj->engineGetAlgoName(((HcfRandImpl *)self)->spiObj); 100} 101 102static HcfResult SetSeed(HcfRand *self, HcfBlob *seed) 103{ 104 if ((self == NULL) || (!HcfIsBlobValid(seed)) || (seed->len > INT_MAX)) { 105 LOGE("The input self ptr is NULL!"); 106 return HCF_INVALID_PARAMS; 107 } 108 if (!HcfIsClassMatch((HcfObjectBase *)self, GetRandClass())) { 109 LOGE("Class is not match."); 110 return HCF_INVALID_PARAMS; 111 } 112 ((HcfRandImpl *)self)->spiObj->engineSetSeed( 113 ((HcfRandImpl *)self)->spiObj, seed); 114 return HCF_SUCCESS; 115} 116 117static void HcfRandDestroy(HcfObjectBase *self) 118{ 119 if (self == NULL) { 120 LOGE("The input self ptr is NULL!"); 121 return; 122 } 123 if (!HcfIsClassMatch((HcfObjectBase *)self, GetRandClass())) { 124 LOGE("Class is not match."); 125 return; 126 } 127 HcfRandImpl *impl = (HcfRandImpl *)self; 128 HcfObjDestroy(impl->spiObj); 129 HcfFree(impl); 130} 131 132HcfResult HcfRandCreate(HcfRand **random) 133{ 134 if (random == NULL) { 135 LOGE("Invalid input params while creating rand!"); 136 return HCF_INVALID_PARAMS; 137 } 138#ifdef CRYPTO_MBEDTLS 139 HcfRandSpiCreateFunc createSpiFunc = FindAbility("MbedtlsRand"); 140#else 141 HcfRandSpiCreateFunc createSpiFunc = FindAbility("OpensslRand"); 142#endif 143 if (createSpiFunc == NULL) { 144 LOGE("Algo not supported!"); 145 return HCF_NOT_SUPPORT; 146 } 147 HcfRandImpl *returnRandApi = (HcfRandImpl *)HcfMalloc(sizeof(HcfRandImpl), 0); 148 if (returnRandApi == NULL) { 149 LOGE("Failed to allocate Rand Obj memory!"); 150 return HCF_ERR_MALLOC; 151 } 152 HcfRandSpi *spiObj = NULL; 153 HcfResult res = createSpiFunc(&spiObj); 154 if (res != HCF_SUCCESS) { 155 LOGE("Failed to create spi object!"); 156 HcfFree(returnRandApi); 157 return res; 158 } 159 returnRandApi->base.base.getClass = GetRandClass; 160 returnRandApi->base.base.destroy = HcfRandDestroy; 161 returnRandApi->base.generateRandom = GenerateRandom; 162 returnRandApi->base.getAlgoName = GetAlgoName; 163 returnRandApi->base.setSeed = SetSeed; 164 returnRandApi->spiObj = spiObj; 165 *random = (HcfRand *)returnRandApi; 166 return HCF_SUCCESS; 167}