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 #include "rand_openssl.h"
22 #include "log.h"
23 #include "config.h"
24 #include "memory.h"
25 #include "utils.h"
26
27 typedef HcfResult (*HcfRandSpiCreateFunc)(HcfRandSpi **);
28
29 typedef struct {
30 HcfRand base;
31
32 HcfRandSpi *spiObj;
33
34 const char *algoName;
35 } HcfRandImpl;
36
37 typedef struct {
38 char *algoName;
39
40 HcfRandSpiCreateFunc createSpiFunc;
41 } HcfRandAbility;
42
43 static const HcfRandAbility RAND_ABILITY_SET[] = {
44 { "OpensslRand", HcfRandSpiCreate }
45 };
46
GetRandClass(void)47 static const char *GetRandClass(void)
48 {
49 return "Rand";
50 }
51
FindAbility(const char * algoName)52 static HcfRandSpiCreateFunc FindAbility(const char *algoName)
53 {
54 for (uint32_t i = 0; i < (sizeof(RAND_ABILITY_SET) / sizeof(RAND_ABILITY_SET[0])); i++) {
55 if (strcmp(RAND_ABILITY_SET[i].algoName, algoName) == 0) {
56 return RAND_ABILITY_SET[i].createSpiFunc;
57 }
58 }
59 LOGE("Algo not support! [Algo]: %s", algoName);
60 return NULL;
61 }
62
GenerateRandom(HcfRand * self,int32_t numBytes,HcfBlob * random)63 static HcfResult GenerateRandom(HcfRand *self, int32_t numBytes, HcfBlob *random)
64 {
65 if ((self == NULL) || (random == NULL)) {
66 LOGE("Invalid params!");
67 return HCF_INVALID_PARAMS;
68 }
69 if (numBytes <= 0) {
70 LOGE("Invalid numBytes!");
71 return HCF_INVALID_PARAMS;
72 }
73 if (!IsClassMatch((HcfObjectBase *)self, GetRandClass())) {
74 LOGE("Class is not match.");
75 return HCF_INVALID_PARAMS;
76 }
77 return ((HcfRandImpl *)self)->spiObj->engineGenerateRandom(
78 ((HcfRandImpl *)self)->spiObj, numBytes, random);
79 }
80
GetAlgoName(HcfRand * self)81 static const char *GetAlgoName(HcfRand *self)
82 {
83 if (self == NULL) {
84 LOGE("The input self ptr is NULL!");
85 return NULL;
86 }
87 if (!IsClassMatch((HcfObjectBase *)self, GetRandClass())) {
88 LOGE("Class is not match!");
89 return NULL;
90 }
91 return ((HcfRandImpl *)self)->spiObj->engineGetAlgoName(((HcfRandImpl *)self)->spiObj);
92 }
93
SetSeed(HcfRand * self,HcfBlob * seed)94 static HcfResult SetSeed(HcfRand *self, HcfBlob *seed)
95 {
96 if ((self == NULL) || (!IsBlobValid(seed)) || (seed->len > INT_MAX)) {
97 LOGE("The input self ptr is NULL!");
98 return HCF_INVALID_PARAMS;
99 }
100 if (!IsClassMatch((HcfObjectBase *)self, GetRandClass())) {
101 LOGE("Class is not match.");
102 return HCF_INVALID_PARAMS;
103 }
104 ((HcfRandImpl *)self)->spiObj->engineSetSeed(
105 ((HcfRandImpl *)self)->spiObj, seed);
106 return HCF_SUCCESS;
107 }
108
HcfRandDestroy(HcfObjectBase * self)109 static void HcfRandDestroy(HcfObjectBase *self)
110 {
111 if (self == NULL) {
112 LOGE("The input self ptr is NULL!");
113 return;
114 }
115 if (!IsClassMatch((HcfObjectBase *)self, GetRandClass())) {
116 LOGE("Class is not match.");
117 return;
118 }
119 HcfRandImpl *impl = (HcfRandImpl *)self;
120 HcfObjDestroy(impl->spiObj);
121 HcfFree(impl);
122 }
123
HcfRandCreate(HcfRand ** random)124 HcfResult HcfRandCreate(HcfRand **random)
125 {
126 if (random == NULL) {
127 LOGE("Invalid input params while creating rand!");
128 return HCF_INVALID_PARAMS;
129 }
130 HcfRandSpiCreateFunc createSpiFunc = FindAbility("OpensslRand");
131 if (createSpiFunc == NULL) {
132 LOGE("Algo not supported!");
133 return HCF_NOT_SUPPORT;
134 }
135 HcfRandImpl *returnRandApi = (HcfRandImpl *)HcfMalloc(sizeof(HcfRandImpl), 0);
136 if (returnRandApi == NULL) {
137 LOGE("Failed to allocate Rand Obj memory!");
138 return HCF_ERR_MALLOC;
139 }
140 HcfRandSpi *spiObj = NULL;
141 HcfResult res = createSpiFunc(&spiObj);
142 if (res != HCF_SUCCESS) {
143 LOGE("Failed to create spi object!");
144 HcfFree(returnRandApi);
145 return res;
146 }
147 returnRandApi->base.base.getClass = GetRandClass;
148 returnRandApi->base.base.destroy = HcfRandDestroy;
149 returnRandApi->base.generateRandom = GenerateRandom;
150 returnRandApi->base.getAlgoName = GetAlgoName;
151 returnRandApi->base.setSeed = SetSeed;
152 returnRandApi->spiObj = spiObj;
153 *random = (HcfRand *)returnRandApi;
154 return HCF_SUCCESS;
155 }