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
31 typedef HcfResult (*HcfRandSpiCreateFunc)(HcfRandSpi **);
32
33 typedef struct {
34 HcfRand base;
35
36 HcfRandSpi *spiObj;
37
38 const char *algoName;
39 } HcfRandImpl;
40
41 typedef struct {
42 char *algoName;
43
44 HcfRandSpiCreateFunc createSpiFunc;
45 } HcfRandAbility;
46
GetRandClass(void)47 static const char *GetRandClass(void)
48 {
49 return "Rand";
50 }
51
52 static const HcfRandAbility RAND_ABILITY_SET[] = {
53 #ifdef CRYPTO_MBEDTLS
54 { "MbedtlsRand", MbedtlsRandSpiCreate }
55 #else
56 { "OpensslRand", HcfRandSpiCreate }
57 #endif
58 };
59
FindAbility(const char *algoName)60 static 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
GenerateRandom(HcfRand *self, int32_t numBytes, HcfBlob *random)71 static 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
GetAlgoName(HcfRand *self)89 static 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
SetSeed(HcfRand *self, HcfBlob *seed)102 static 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
HcfRandDestroy(HcfObjectBase *self)117 static 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
HcfRandCreate(HcfRand **random)132 HcfResult 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 }