1 /*
2 * Copyright (C) 2024 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 "mbedtls_rand.h"
17
18 #include "mbedtls/entropy.h"
19 #include "mbedtls/ctr_drbg.h"
20 #include "securec.h"
21 #include "log.h"
22 #include "memory.h"
23 #include "utils.h"
24
25 typedef struct {
26 HcfRandSpi base;
27 mbedtls_entropy_context *entropy;
28 mbedtls_ctr_drbg_context *ctrDrbg;
29 } HcfRandSpiImpl;
30
GetMbedtlsRandClass(void)31 static const char *GetMbedtlsRandClass(void)
32 {
33 return "RandMbedtls";
34 }
35
MbedtlsGetMdEntropy(HcfRandSpi *self)36 static mbedtls_entropy_context *MbedtlsGetMdEntropy(HcfRandSpi *self)
37 {
38 if (!HcfIsClassMatch((HcfObjectBase *)self, GetMbedtlsRandClass())) {
39 LOGE("Class is not match.");
40 return NULL;
41 }
42
43 return ((HcfRandSpiImpl *)self)->entropy;
44 }
45
MbedtlsGetMdCtrDrbg(HcfRandSpi *self)46 static mbedtls_ctr_drbg_context *MbedtlsGetMdCtrDrbg(HcfRandSpi *self)
47 {
48 if (!HcfIsClassMatch((HcfObjectBase *)self, GetMbedtlsRandClass())) {
49 LOGE("Class is not match.");
50 return NULL;
51 }
52 return ((HcfRandSpiImpl *)self)->ctrDrbg;
53 }
54
MbedtlsGenerateRandom(HcfRandSpi *self, int32_t numBytes, HcfBlob *random)55 static HcfResult MbedtlsGenerateRandom(HcfRandSpi *self, int32_t numBytes, HcfBlob *random)
56 {
57 if ((self == NULL) || (random == NULL)) {
58 LOGE("Invalid params!");
59 return HCF_INVALID_PARAMS;
60 }
61 if (numBytes <= 0) {
62 LOGE("Invalid numBytes!");
63 return HCF_INVALID_PARAMS;
64 }
65 mbedtls_ctr_drbg_context *ctrDrbg = MbedtlsGetMdCtrDrbg(self);
66 if (ctrDrbg == NULL) {
67 LOGE("Invalid ctrDrbg null!");
68 return HCF_INVALID_PARAMS;
69 }
70 random->data = (uint8_t *)HcfMalloc(numBytes, 0);
71 if (random->data == NULL) {
72 LOGE("Failed to allocate random->data memory!");
73 return HCF_ERR_MALLOC;
74 }
75 int32_t ret = mbedtls_ctr_drbg_random(ctrDrbg, random->data, numBytes);
76 if (ret != 0) {
77 LOGE("RAND_bytes return is %d error!", ret);
78 HcfFree(random->data);
79 random->data = NULL;
80 return HCF_ERR_CRYPTO_OPERATION;
81 }
82 random->len = numBytes;
83
84 return HCF_SUCCESS;
85 }
86
MbedtlsGetRandAlgoName(HcfRandSpi *self)87 static const char *MbedtlsGetRandAlgoName(HcfRandSpi *self)
88 {
89 if (self == NULL) {
90 LOGE("Invalid input parameter.");
91 return NULL;
92 }
93 if (!HcfIsClassMatch((HcfObjectBase *)self, GetMbedtlsRandClass())) {
94 LOGE("Class is not match.");
95 return NULL;
96 }
97
98 return MBEDTLS_RAND_ALGORITHM;
99 }
100
MbedtlsSetSeed(HcfRandSpi *self, HcfBlob *seed)101 static void MbedtlsSetSeed(HcfRandSpi *self, HcfBlob *seed)
102 {
103 if ((self == NULL) || (seed == NULL)) {
104 LOGE("Invalid params!");
105 return;
106 }
107 if ((seed->data == NULL) || (seed->len == 0)) {
108 LOGE("Invalid numBytes!");
109 return;
110 }
111 mbedtls_ctr_drbg_context *ctrDrbg = MbedtlsGetMdCtrDrbg(self);
112 if (ctrDrbg == NULL) {
113 LOGE("Invalid ctrDrbg params!");
114 return;
115 }
116 mbedtls_entropy_context *entropy = MbedtlsGetMdEntropy(self);
117 if (entropy == NULL) {
118 LOGE("Invalid entropy params!");
119 return;
120 }
121 int32_t ret = mbedtls_ctr_drbg_seed(ctrDrbg, mbedtls_entropy_func, entropy,
122 (const unsigned char *)seed->data, seed->len);
123 if (ret != 0) {
124 LOGE("seed return is %d error!", ret);
125 return;
126 }
127 }
128
DestroyMbedtlsRand(HcfObjectBase *self)129 static void DestroyMbedtlsRand(HcfObjectBase *self)
130 {
131 if (self == NULL) {
132 LOGE("Self ptr is NULL!");
133 return;
134 }
135 if (!HcfIsClassMatch(self, GetMbedtlsRandClass())) {
136 LOGE("Class is not match.");
137 return;
138 }
139 mbedtls_ctr_drbg_context *ctrDrbg = MbedtlsGetMdCtrDrbg((HcfRandSpi *)self);
140 if (ctrDrbg != NULL) {
141 mbedtls_ctr_drbg_free(ctrDrbg);
142 HcfFree(ctrDrbg);
143 }
144 mbedtls_entropy_context *entropy = MbedtlsGetMdEntropy((HcfRandSpi *)self);
145 if (entropy != NULL) {
146 mbedtls_entropy_free(entropy);
147 HcfFree(entropy);
148 }
149 HcfFree(self);
150 }
151
MbedtlsRandInitEx(mbedtls_entropy_context **entropy, mbedtls_ctr_drbg_context **ctrDrbg)152 static int32_t MbedtlsRandInitEx(mbedtls_entropy_context **entropy, mbedtls_ctr_drbg_context **ctrDrbg)
153 {
154 if ((entropy == NULL) || (ctrDrbg == NULL)) {
155 LOGE("Invalid input parameter.");
156 return HCF_INVALID_PARAMS;
157 }
158 *entropy = (mbedtls_entropy_context *)HcfMalloc(sizeof(mbedtls_entropy_context), 0);
159 if (*entropy == NULL) {
160 LOGE("Failed to allocate *entropy memory!");
161 return HCF_ERR_MALLOC;
162 }
163 *ctrDrbg = (mbedtls_ctr_drbg_context *)HcfMalloc(sizeof(mbedtls_ctr_drbg_context), 0);
164 if (*ctrDrbg == NULL) {
165 HcfFree(*entropy);
166 LOGE("Failed to allocate *ctrDrbg memory!");
167 return HCF_ERR_MALLOC;
168 }
169 mbedtls_entropy_init(*entropy);
170 mbedtls_ctr_drbg_init(*ctrDrbg);
171 int32_t ret = mbedtls_ctr_drbg_seed(*ctrDrbg, mbedtls_entropy_func, *entropy, NULL, 0);
172 if (ret != 0) {
173 LOGE("Failed seed ret is %d!", ret);
174 mbedtls_entropy_free(*entropy);
175 mbedtls_ctr_drbg_free(*ctrDrbg);
176 HcfFree(*entropy);
177 HcfFree(*ctrDrbg);
178 return HCF_ERR_CRYPTO_OPERATION;
179 }
180
181 return HCF_SUCCESS;
182 }
183
MbedtlsRandSpiCreate(HcfRandSpi **spiObj)184 HcfResult MbedtlsRandSpiCreate(HcfRandSpi **spiObj)
185 {
186 if (spiObj == NULL) {
187 LOGE("Invalid input parameter.");
188 return HCF_INVALID_PARAMS;
189 }
190 HcfRandSpiImpl *returnSpiImpl = (HcfRandSpiImpl *)HcfMalloc(sizeof(HcfRandSpiImpl), 0);
191 if (returnSpiImpl == NULL) {
192 LOGE("Failed to allocate *returnSpiImpl memory!");
193 return HCF_ERR_MALLOC;
194 }
195 int32_t ret = MbedtlsRandInitEx(&(returnSpiImpl->entropy), &(returnSpiImpl->ctrDrbg));
196 if (ret != HCF_SUCCESS) {
197 LOGE("Failed to allocate entropy ctrDrbg memory!");
198 return HCF_ERR_MALLOC;
199 }
200 returnSpiImpl->base.base.getClass = GetMbedtlsRandClass;
201 returnSpiImpl->base.base.destroy = DestroyMbedtlsRand;
202 returnSpiImpl->base.engineGenerateRandom = MbedtlsGenerateRandom;
203 returnSpiImpl->base.engineSetSeed = MbedtlsSetSeed;
204 returnSpiImpl->base.engineGetAlgoName = MbedtlsGetRandAlgoName;
205 *spiObj = (HcfRandSpi *)returnSpiImpl;
206
207 return HCF_SUCCESS;
208 }
209