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