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 "hcfkdfcreate_fuzzer.h"
17
18 #include <cstddef>
19 #include <cstdint>
20 #include <string>
21 #include "securec.h"
22 #include "detailed_hkdf_params.h"
23 #include "detailed_pbkdf2_params.h"
24 #include "object_base.h"
25 #include "blob.h"
26 #include "kdf.h"
27 #include "result.h"
28
29 namespace OHOS {
30 static const char *g_testKdfAlg[] = { "HKDF|SHA1", "HKDF|SHA224", "HKDF|SHA256", "HKDF|SHA384", "HKDF|SHA512",
31 "HKDF|SM3", "PBKDF2|SHA1", "PBKDF2|SHA224", "PBKDF2|SHA256", "PBKDF2|SHA384",
32 "PBKDF2|SHA512", "PBKDF2|SM3"};
33 static const char *g_keyData = "012345678901234567890123456789";
34 static const char *g_infoData = "infostring";
35 static const char *g_saltData = "saltstring";
36 constexpr uint32_t OUT_PUT_MAX_LENGTH = 128;
37 constexpr uint32_t OUT_PUT_NORMAL_LENGTH = 32;
38 constexpr uint32_t SALT_NORMAL_LENGTH = 16;
39
TestHkdfGenerateSecretSalt(const char * kdfAlg,const uint8_t * data,size_t size)40 static void TestHkdfGenerateSecretSalt(const char *kdfAlg, const uint8_t* data, size_t size)
41 {
42 HcfKdf *generator = nullptr;
43 HcfResult ret = HcfKdfCreate(kdfAlg, &generator);
44 if (ret != HCF_SUCCESS) {
45 return;
46 }
47 uint8_t out[OUT_PUT_MAX_LENGTH] = {0};
48 HcfBlob output = {.data = out, .len = OUT_PUT_NORMAL_LENGTH};
49 HcfBlob salt = {.data = const_cast<uint8_t *>(data), .len = size};
50 HcfBlob key = {.data = reinterpret_cast<uint8_t *>(const_cast<char *>(g_keyData)),
51 .len = strlen(g_keyData)};
52 HcfBlob info = {.data = reinterpret_cast<uint8_t *>(const_cast<char *>(g_infoData)),
53 .len = strlen(g_infoData)};
54 HcfHkdfParamsSpec params = {
55 .base = { .algName = "HKDF", },
56 .key = key,
57 .salt = salt,
58 .info = info,
59 .output = output,
60 };
61 if (generator != nullptr) {
62 generator->generateSecret(generator, &(params.base));
63 }
64 HcfObjDestroy(generator);
65 }
66
TestHkdfGenerateSecretKey(const char * kdfAlg,const uint8_t * data,size_t size)67 static void TestHkdfGenerateSecretKey(const char *kdfAlg, const uint8_t* data, size_t size)
68 {
69 HcfKdf *generator = nullptr;
70 HcfResult ret = HcfKdfCreate(kdfAlg, &generator);
71 if (ret != HCF_SUCCESS) {
72 return;
73 }
74 uint8_t out[OUT_PUT_MAX_LENGTH] = {0};
75 HcfBlob output = {.data = out, .len = OUT_PUT_NORMAL_LENGTH};
76 HcfBlob key = {.data = const_cast<uint8_t *>(data), .len = size};
77 HcfBlob salt = {.data = reinterpret_cast<uint8_t *>(const_cast<char *>(g_saltData)),
78 .len = strlen(g_saltData)};
79 HcfBlob info = {.data = reinterpret_cast<uint8_t *>(const_cast<char *>(g_infoData)),
80 .len = strlen(g_infoData)};
81 HcfHkdfParamsSpec params = {
82 .base = { .algName = "HKDF", },
83 .key = key,
84 .salt = salt,
85 .info = info,
86 .output = output,
87 };
88 if (generator != nullptr) {
89 generator->generateSecret(generator, &(params.base));
90 }
91 HcfObjDestroy(generator);
92 }
93
TestHkdfGenerateSecretInfo(const char * kdfAlg,const uint8_t * data,size_t size)94 static void TestHkdfGenerateSecretInfo(const char *kdfAlg, const uint8_t* data, size_t size)
95 {
96 HcfKdf *generator = nullptr;
97 HcfResult ret = HcfKdfCreate(kdfAlg, &generator);
98 if (ret != HCF_SUCCESS) {
99 return;
100 }
101 uint8_t out[OUT_PUT_MAX_LENGTH] = {0};
102 HcfBlob output = {.data = out, .len = OUT_PUT_NORMAL_LENGTH};
103 HcfBlob info = {.data = const_cast<uint8_t *>(data), .len = size};
104 HcfBlob key = {.data = reinterpret_cast<uint8_t *>(const_cast<char *>(g_keyData)),
105 .len = strlen(g_keyData)};
106 HcfBlob salt = {.data = reinterpret_cast<uint8_t *>(const_cast<char *>(g_saltData)),
107 .len = strlen(g_saltData)};
108 HcfHkdfParamsSpec params = {
109 .base = { .algName = "HKDF", },
110 .key = key,
111 .salt = salt,
112 .info = info,
113 .output = output,
114 };
115 if (generator != nullptr) {
116 generator->generateSecret(generator, &(params.base));
117 }
118 HcfObjDestroy(generator);
119 }
120
TestPbkdfGenerateSecretWithoutInfo(const char * kdfAlg,const uint8_t * data,size_t size)121 static void TestPbkdfGenerateSecretWithoutInfo(const char *kdfAlg, const uint8_t* data, size_t size)
122 {
123 HcfKdf *generator = nullptr;
124 HcfResult ret = HcfKdfCreate(kdfAlg, &generator);
125 if (ret != HCF_SUCCESS) {
126 return;
127 }
128 uint8_t out[OUT_PUT_MAX_LENGTH] = {0};
129 uint8_t saltData[SALT_NORMAL_LENGTH] = {0};
130 HcfBlob output = {.data = out, .len = OUT_PUT_NORMAL_LENGTH};
131 HcfBlob salt = {.data = saltData, .len = SALT_NORMAL_LENGTH};
132 HcfBlob password = {.data = const_cast<uint8_t *>(data), .len = size};
133 HcfPBKDF2ParamsSpec params = {
134 .base = { .algName = "PBKDF2", },
135 .password = password,
136 .salt = salt,
137 .iterations = 10000,
138 .output = output,
139 };
140 ret = generator->generateSecret(generator, &(params.base));
141 HcfObjDestroy(generator);
142 }
143
TestGetOneAlgoName(const char * kdfAlg)144 static void TestGetOneAlgoName(const char *kdfAlg)
145 {
146 HcfKdf *generator = nullptr;
147 HcfResult ret = HcfKdfCreate(kdfAlg, &generator);
148 if (ret != HCF_SUCCESS) {
149 return;
150 }
151 if (generator != nullptr) {
152 generator->getAlgorithm(generator);
153 }
154 }
155
TestGenerateSecret(const char * kdfAlg,const uint8_t * data,size_t size)156 static void TestGenerateSecret(const char *kdfAlg, const uint8_t* data, size_t size)
157 {
158 TestHkdfGenerateSecretSalt(kdfAlg, data, size);
159 TestHkdfGenerateSecretKey(kdfAlg, data, size);
160 TestHkdfGenerateSecretInfo(kdfAlg, data, size);
161 TestPbkdfGenerateSecretWithoutInfo(kdfAlg, data, size);
162 }
163
HcfKdfCreateFuzzTest(const uint8_t * data,size_t size)164 bool HcfKdfCreateFuzzTest(const uint8_t* data, size_t size)
165 {
166 std::string kdfData(reinterpret_cast<const char *>(data), size);
167 TestGetOneAlgoName(kdfData.c_str());
168 for (size_t i = 0; i < sizeof(g_testKdfAlg) / sizeof(g_testKdfAlg[0]); i++) {
169 const char *algoName = g_testKdfAlg[i];
170 TestGenerateSecret(algoName, data, size);
171 HcfKdf *generator = nullptr;
172 HcfResult res = HcfKdfCreate(algoName, &generator);
173 if (res != HCF_SUCCESS) {
174 return false;
175 }
176 HcfObjDestroy(generator);
177 }
178 return true;
179 }
180 }
181
182 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)183 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
184 {
185 /* Run your code on data */
186 OHOS::HcfKdfCreateFuzzTest(data, size);
187 return 0;
188 }
189