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 "hcfsm2create_fuzzer.h"
17
18 #include <cstddef>
19 #include <cstdint>
20 #include <string>
21 #include "securec.h"
22
23 #include "blob.h"
24 #include "memory.h"
25 #include "sm2_crypto_params.h"
26 #include "sm2_crypto_util.h"
27 #include "result.h"
28
29 namespace OHOS {
30 static const char *g_sm2ModeC1C3C2 = "C1C3C2";
31 static const int INPUT_LEN = 121;
32 static uint8_t g_input[INPUT_LEN] = {
33 48, 119, 2, 33, 0, 183, 70, 70, 149, 188, 64, 6, 110, 236, 85, 149, 216, 224, 102, 95, 92, 41, 105, 232, 5,
34 248, 122, 21, 174, 43, 226, 221, 104, 82, 88, 153, 45, 2, 32, 96, 229, 78, 209, 233, 110, 5, 149, 91, 110,
35 109, 181, 17, 75, 109, 146, 128, 170, 113, 205, 158, 193, 156, 90, 110, 40, 18, 119, 247, 198, 93, 107, 4,
36 32, 87, 167, 167, 247, 88, 146, 203, 234, 83, 126, 117, 129, 52, 142, 82, 54, 152, 226, 201, 111, 143, 115,
37 169, 125, 128, 42, 157, 31, 114, 198, 109, 244, 4, 14, 100, 227, 78, 195, 249, 179, 43, 70, 242, 69, 169, 10,
38 65, 123
39 };
40 static HcfBlob g_correctInput = {
41 .data = g_input,
42 .len = INPUT_LEN
43 };
44 static const int X_COORDINATE_LEN = 32;
45 static unsigned char g_xCoordinate[] = {
46 45, 153, 88, 82, 104, 221, 226, 43, 174, 21, 122, 248, 5, 232, 105, 41, 92, 95, 102, 224, 216, 149, 85, 236,
47 110, 6, 64, 188, 149, 70, 70, 183
48 };
49 static const int Y_COORDINATE_LEN = 32;
50 static unsigned char g_yCoordinate[] = {
51 107, 93, 198, 247, 119, 18, 40, 110, 90, 156, 193, 158, 205, 113, 170, 128, 146, 109, 75, 17, 181, 109, 110,
52 91, 149, 5, 110, 233, 209, 78, 229, 96
53 };
54 static const int HASH_DATA_LEN = 32;
55 static unsigned char g_hashData[] = {
56 87, 167, 167, 247, 88, 146, 203, 234, 83, 126, 117, 129, 52, 142, 82, 54, 152, 226, 201, 111, 143, 115, 169,
57 125, 128, 42, 157, 31, 114, 198, 109, 244
58 };
59 static const int CIPHER_TEXT_DATA_LEN = 14;
60 static unsigned char g_cipherTextData[] = {
61 100, 227, 78, 195, 249, 179, 43, 70, 242, 69, 169, 10, 65, 123
62 };
63
ConstructCorrectSm2CipherTextXSpec(Sm2CipherTextSpec ** spec,const uint8_t * data,size_t size)64 HcfResult ConstructCorrectSm2CipherTextXSpec(Sm2CipherTextSpec **spec, const uint8_t* data, size_t size)
65 {
66 Sm2CipherTextSpec *tempSpec = static_cast<Sm2CipherTextSpec *>(HcfMalloc(sizeof(Sm2CipherTextSpec), 0));
67 if (tempSpec == nullptr) {
68 return HCF_ERR_MALLOC;
69 }
70 tempSpec->xCoordinate.data = const_cast<unsigned char*>(data);
71 tempSpec->xCoordinate.len = static_cast<uint32_t>(size);
72 tempSpec->yCoordinate.data = g_yCoordinate;
73 tempSpec->yCoordinate.len = Y_COORDINATE_LEN;
74 tempSpec->cipherTextData.data = g_cipherTextData;
75 tempSpec->cipherTextData.len = CIPHER_TEXT_DATA_LEN;
76 tempSpec->hashData.data = g_hashData;
77 tempSpec->hashData.len = HASH_DATA_LEN;
78 *spec = tempSpec;
79 return HCF_SUCCESS;
80 }
81
ConstructCorrectSm2CipherTextYSpec(Sm2CipherTextSpec ** spec,const uint8_t * data,size_t size)82 HcfResult ConstructCorrectSm2CipherTextYSpec(Sm2CipherTextSpec **spec, const uint8_t* data, size_t size)
83 {
84 Sm2CipherTextSpec *tempSpec = static_cast<Sm2CipherTextSpec *>(HcfMalloc(sizeof(Sm2CipherTextSpec), 0));
85 if (tempSpec == nullptr) {
86 return HCF_ERR_MALLOC;
87 }
88 tempSpec->xCoordinate.data = g_xCoordinate;
89 tempSpec->xCoordinate.len = X_COORDINATE_LEN;
90 tempSpec->yCoordinate.data = const_cast<unsigned char*>(data);
91 tempSpec->yCoordinate.len = static_cast<uint32_t>(size);
92 tempSpec->cipherTextData.data = g_cipherTextData;
93 tempSpec->cipherTextData.len = CIPHER_TEXT_DATA_LEN;
94 tempSpec->hashData.data = g_hashData;
95 tempSpec->hashData.len = HASH_DATA_LEN;
96 *spec = tempSpec;
97 return HCF_SUCCESS;
98 }
99
ConstructCorrectSm2CipherTextSpec(Sm2CipherTextSpec ** spec,const uint8_t * data,size_t size)100 HcfResult ConstructCorrectSm2CipherTextSpec(Sm2CipherTextSpec **spec, const uint8_t* data, size_t size)
101 {
102 Sm2CipherTextSpec *tempSpec = static_cast<Sm2CipherTextSpec *>(HcfMalloc(sizeof(Sm2CipherTextSpec), 0));
103 if (tempSpec == nullptr) {
104 return HCF_ERR_MALLOC;
105 }
106 tempSpec->xCoordinate.data = g_xCoordinate;
107 tempSpec->xCoordinate.len = X_COORDINATE_LEN;
108 tempSpec->yCoordinate.data = g_yCoordinate;
109 tempSpec->yCoordinate.len = Y_COORDINATE_LEN;
110 tempSpec->cipherTextData.data = const_cast<uint8_t *>(data);
111 tempSpec->cipherTextData.len = size;
112 tempSpec->hashData.data = g_hashData;
113 tempSpec->hashData.len = HASH_DATA_LEN;
114 *spec = tempSpec;
115 return HCF_SUCCESS;
116 }
117
TestHcfGenCipherTextBySpec(const uint8_t * data,size_t size)118 static void TestHcfGenCipherTextBySpec(const uint8_t* data, size_t size)
119 {
120 if ((data == nullptr) || size < sizeof(uint32_t)) {
121 return;
122 }
123
124 int res = 0;
125 Sm2CipherTextSpec *spec = nullptr;
126 res = ConstructCorrectSm2CipherTextSpec(&spec, data, size);
127 if (res != HCF_SUCCESS) {
128 return;
129 }
130 HcfBlob output = { .data = nullptr, .len = 0 };
131 res = HcfGenCipherTextBySpec(spec, g_sm2ModeC1C3C2, &output);
132 if (res != HCF_SUCCESS) {
133 HcfFree(spec);
134 return;
135 }
136 if (g_correctInput.len == output.len) {
137 (void)memcmp(output.data, g_correctInput.data, g_correctInput.len);
138 }
139 HcfBlobDataFree(&output);
140 HcfFree(spec);
141 }
142
TestHcfGenCipherTextByXSpec(const uint8_t * data,size_t size)143 static void TestHcfGenCipherTextByXSpec(const uint8_t* data, size_t size)
144 {
145 if ((data == nullptr) || size < sizeof(uint32_t)) {
146 return;
147 }
148
149 int res = 0;
150 Sm2CipherTextSpec *spec = nullptr;
151 res = ConstructCorrectSm2CipherTextXSpec(&spec, data, size);
152 if (res != HCF_SUCCESS) {
153 return;
154 }
155 HcfBlob output = { .data = nullptr, .len = 0 };
156 res = HcfGenCipherTextBySpec(spec, g_sm2ModeC1C3C2, &output);
157 if (res != HCF_SUCCESS) {
158 HcfFree(spec);
159 return;
160 }
161 if (g_correctInput.len == output.len) {
162 (void)memcmp(output.data, g_correctInput.data, g_correctInput.len);
163 }
164 HcfBlobDataFree(&output);
165 HcfFree(spec);
166 }
167
TestHcfGenCipherTextByYSpec(const uint8_t * data,size_t size)168 static void TestHcfGenCipherTextByYSpec(const uint8_t* data, size_t size)
169 {
170 if ((data == nullptr) || size < sizeof(uint32_t)) {
171 return;
172 }
173
174 int res = 0;
175 Sm2CipherTextSpec *spec = nullptr;
176 res = ConstructCorrectSm2CipherTextYSpec(&spec, data, size);
177 if (res != HCF_SUCCESS) {
178 return;
179 }
180 HcfBlob output = { .data = nullptr, .len = 0 };
181 res = HcfGenCipherTextBySpec(spec, g_sm2ModeC1C3C2, &output);
182 if (res != HCF_SUCCESS) {
183 HcfFree(spec);
184 return;
185 }
186 if (g_correctInput.len == output.len) {
187 (void)memcmp(output.data, g_correctInput.data, g_correctInput.len);
188 }
189 HcfBlobDataFree(&output);
190 HcfFree(spec);
191 }
192
TestHcfGetCipherTextSpec(const uint8_t * data,size_t size)193 static void TestHcfGetCipherTextSpec(const uint8_t* data, size_t size)
194 {
195 if ((data == nullptr) || size < sizeof(uint32_t)) {
196 return;
197 }
198
199 Sm2CipherTextSpec *spec = nullptr;
200 char *sm2Mode = reinterpret_cast<char *>(HcfMalloc(size + 1, 0));
201 if (sm2Mode == nullptr) {
202 return;
203 }
204 if (memcpy_s(sm2Mode, size, data, size) != EOK) {
205 HcfFree(sm2Mode);
206 return;
207 }
208 HcfResult res = HcfGetCipherTextSpec(&g_correctInput, sm2Mode, &spec);
209 HcfFree(sm2Mode);
210 if (res != HCF_SUCCESS) {
211 return;
212 }
213 DestroySm2CipherTextSpec(spec);
214 }
215
HcfSm2CreateFuzzTest(const uint8_t * data,size_t size)216 bool HcfSm2CreateFuzzTest(const uint8_t* data, size_t size)
217 {
218 TestHcfGenCipherTextBySpec(data, size);
219 TestHcfGenCipherTextByXSpec(data, size);
220 TestHcfGenCipherTextByYSpec(data, size);
221 TestHcfGetCipherTextSpec(data, size);
222
223 Sm2CipherTextSpec spec = {};
224 spec.xCoordinate.data = g_xCoordinate;
225 spec.xCoordinate.len = X_COORDINATE_LEN;
226 spec.yCoordinate.data = g_yCoordinate;
227 spec.yCoordinate.len = Y_COORDINATE_LEN;
228 spec.cipherTextData.data = g_cipherTextData;
229 spec.cipherTextData.len = CIPHER_TEXT_DATA_LEN;
230 spec.hashData.data = g_hashData;
231 spec.hashData.len = HASH_DATA_LEN;
232
233 HcfBlob output = { .data = nullptr, .len = 0 };
234 HcfGenCipherTextBySpec(&spec, g_sm2ModeC1C3C2, &output);
235 HcfBlobDataFree(&output);
236 return true;
237 }
238 }
239
240 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)241 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
242 {
243 /* Run your code on data */
244 OHOS::HcfSm2CreateFuzzTest(data, size);
245 return 0;
246 }
247