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 "hcfsigncreate_fuzzer.h"
17 
18 #include <cstddef>
19 #include <cstdint>
20 #include <string>
21 
22 #include "asy_key_generator.h"
23 #include "blob.h"
24 #include "result.h"
25 #include "signature.h"
26 
27 namespace OHOS {
TestSign(const uint8_t * data,size_t size)28     static void TestSign(const uint8_t* data, size_t size)
29     {
30         HcfAsyKeyGenerator *generator = nullptr;
31         HcfResult res = HcfAsyKeyGeneratorCreate("ECC384", &generator);
32         if (res != HCF_SUCCESS) {
33             return;
34         }
35 
36         HcfKeyPair *ecc384KeyPair = nullptr;
37         res = generator->generateKeyPair(generator, nullptr, &ecc384KeyPair);
38         HcfObjDestroy(generator);
39         if (res != HCF_SUCCESS) {
40             return;
41         }
42 
43         HcfSign *sign = nullptr;
44         res = HcfSignCreate("ECC384|SHA384", &sign);
45         if (res != HCF_SUCCESS) {
46             HcfObjDestroy(ecc384KeyPair);
47             return;
48         }
49         static HcfBlob mockInput = {
50             .data = const_cast<uint8_t *>(data),
51             .len = size
52         };
53         (void)sign->init(sign, nullptr, ecc384KeyPair->priKey);
54         (void)sign->update(sign, &mockInput);
55         HcfObjDestroy(ecc384KeyPair);
56         HcfObjDestroy(sign);
57     }
58 
TestSignSm2(const uint8_t * data,size_t size)59     static void TestSignSm2(const uint8_t* data, size_t size)
60     {
61         HcfAsyKeyGenerator *generator = nullptr;
62         HcfResult res = HcfAsyKeyGeneratorCreate("SM2_256", &generator);
63         if (res != HCF_SUCCESS) {
64             return;
65         }
66 
67         HcfKeyPair *sm2256KeyPair = nullptr;
68         res = generator->generateKeyPair(generator, nullptr, &sm2256KeyPair);
69         HcfObjDestroy(generator);
70         if (res != HCF_SUCCESS) {
71             return;
72         }
73 
74         HcfSign *sign = nullptr;
75         res = HcfSignCreate("SM2_256|SM3", &sign);
76         if (res != HCF_SUCCESS) {
77             HcfObjDestroy(sm2256KeyPair);
78             return;
79         }
80         static HcfBlob mockInput = {
81             .data = const_cast<uint8_t *>(data),
82             .len = size
83         };
84         (void)sign->init(sign, nullptr, sm2256KeyPair->priKey);
85         (void)sign->update(sign, &mockInput);
86         HcfObjDestroy(sm2256KeyPair);
87         HcfObjDestroy(sign);
88     }
89 
TestSignBrainpool(const uint8_t * data,size_t size)90     static void TestSignBrainpool(const uint8_t* data, size_t size)
91     {
92         HcfAsyKeyGenerator *generator = nullptr;
93         HcfResult res = HcfAsyKeyGeneratorCreate("ECC_BrainPoolP160r1", &generator);
94         if (res != HCF_SUCCESS) {
95             return;
96         }
97 
98         HcfKeyPair *brainPoolP160r1KeyPair = nullptr;
99         res = generator->generateKeyPair(generator, nullptr, &brainPoolP160r1KeyPair);
100         HcfObjDestroy(generator);
101         if (res != HCF_SUCCESS) {
102             return;
103         }
104 
105         HcfSign *sign = nullptr;
106         res = HcfSignCreate("ECC_BrainPoolP160r1|SHA1", &sign);
107         if (res != HCF_SUCCESS) {
108             HcfObjDestroy(brainPoolP160r1KeyPair);
109             return;
110         }
111         static HcfBlob mockInput = {
112             .data = const_cast<uint8_t *>(data),
113             .len = size
114         };
115         (void)sign->init(sign, nullptr, brainPoolP160r1KeyPair->priKey);
116         (void)sign->update(sign, &mockInput);
117         HcfObjDestroy(brainPoolP160r1KeyPair);
118         HcfObjDestroy(sign);
119     }
120 
TestSignEd25519(const uint8_t * data,size_t size)121         static void TestSignEd25519(const uint8_t* data, size_t size)
122     {
123         HcfAsyKeyGenerator *generator = nullptr;
124         HcfResult res = HcfAsyKeyGeneratorCreate("Ed25519", &generator);
125         if (res != HCF_SUCCESS) {
126             return;
127         }
128 
129         HcfKeyPair *ed25519KeyPair = nullptr;
130         res = generator->generateKeyPair(generator, nullptr, &ed25519KeyPair);
131         HcfObjDestroy(generator);
132         if (res != HCF_SUCCESS) {
133             return;
134         }
135 
136         HcfSign *sign = nullptr;
137         res = HcfSignCreate("Ed25519", &sign);
138         if (res != HCF_SUCCESS) {
139             HcfObjDestroy(ed25519KeyPair);
140             return;
141         }
142         static HcfBlob mockInput = {
143             .data = const_cast<uint8_t *>(data),
144             .len = size
145         };
146         (void)sign->init(sign, nullptr, ed25519KeyPair->priKey);
147         (void)sign->update(sign, &mockInput);
148         HcfObjDestroy(ed25519KeyPair);
149         HcfObjDestroy(sign);
150     }
151 
HcfSignCreateFuzzTest(const uint8_t * data,size_t size)152     bool HcfSignCreateFuzzTest(const uint8_t* data, size_t size)
153     {
154         TestSign(data, size);
155         TestSignSm2(data, size);
156         TestSignBrainpool(data, size);
157         TestSignEd25519(data, size);
158         HcfSign *sign = nullptr;
159         std::string algoName(reinterpret_cast<const char *>(data), size);
160         HcfResult res = HcfSignCreate(algoName.c_str(), &sign);
161         if (res != HCF_SUCCESS) {
162             return false;
163         }
164         HcfObjDestroy(sign);
165         return true;
166     }
167 }
168 
169 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)170 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
171 {
172     /* Run your code on data */
173     OHOS::HcfSignCreateFuzzTest(data, size);
174     return 0;
175 }
176