• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "hcfciphercreate_fuzzer.h"
17 
18 #include <cstddef>
19 #include <cstdint>
20 #include <string>
21 #include "securec.h"
22 
23 #include "asy_key_generator.h"
24 #include "blob.h"
25 #include "cipher.h"
26 #include "mac.h"
27 #include "result.h"
28 #include "sym_key_generator.h"
29 
30 namespace OHOS {
31     static bool g_testFlag = true;
32 
AesEncrypt(HcfCipher * cipher,HcfSymKey * key,HcfParamsSpec * params,uint8_t * cipherText,int * cipherTextLen)33     static int32_t AesEncrypt(HcfCipher *cipher, HcfSymKey *key, HcfParamsSpec *params,
34         uint8_t *cipherText, int *cipherTextLen)
35     {
36         uint8_t plainText[] = "this is test!";
37         HcfBlob input = {.data = reinterpret_cast<uint8_t *>(plainText), .len = 13};
38         HcfBlob output = {};
39         int32_t maxLen = *cipherTextLen;
40         int32_t ret = cipher->init(cipher, ENCRYPT_MODE, &(key->key), params);
41         if (ret != 0) {
42             return ret;
43         }
44 
45         ret = cipher->update(cipher, &input, &output);
46         if (ret != 0) {
47             return ret;
48         }
49         *cipherTextLen = output.len;
50         if (output.len > 0 && output.data != nullptr) {
51             (void)memcpy_s(cipherText, maxLen, output.data, output.len);
52         }
53         if (output.data != nullptr) {
54             HcfBlobDataClearAndFree(&output);
55             output.data = nullptr;
56         }
57         ret = cipher->doFinal(cipher, nullptr, &output);
58         if (ret != 0) {
59             return ret;
60         }
61         if (output.len > 0 && output.data != nullptr) {
62             (void)memcpy_s(cipherText + *cipherTextLen, maxLen - *cipherTextLen, output.data, output.len);
63         }
64         *cipherTextLen += output.len;
65         if (output.data != nullptr) {
66             HcfBlobDataClearAndFree(&output);
67             output.data = nullptr;
68         }
69         return 0;
70     }
71 
AesDecrypt(HcfCipher * cipher,HcfSymKey * key,HcfParamsSpec * params,uint8_t * cipherText,int cipherTextLen)72     static int32_t AesDecrypt(HcfCipher *cipher, HcfSymKey *key, HcfParamsSpec *params,
73         uint8_t *cipherText, int cipherTextLen)
74     {
75         uint8_t plainText[] = "this is test!";
76         HcfBlob input = {.data = cipherText, .len = cipherTextLen};
77         HcfBlob output = {};
78         int32_t maxLen = cipherTextLen;
79         int32_t ret = cipher->init(cipher, DECRYPT_MODE, &(key->key), params);
80         if (ret != 0) {
81             return ret;
82         }
83 
84         ret = cipher->update(cipher, &input, &output);
85         if (ret != 0) {
86             return ret;
87         }
88         if (output.len > 0 && output.data != nullptr) {
89             (void)memcpy_s(cipherText, maxLen, output.data, output.len);
90         }
91         cipherTextLen = output.len;
92         if (output.data != nullptr) {
93             HcfBlobDataClearAndFree(&output);
94             output.data = nullptr;
95             output.len = 0;
96         }
97         ret = cipher->doFinal(cipher, nullptr, &output);
98         if (ret != 0) {
99             return ret;
100         }
101         if (output.len > 0 && output.data != nullptr) {
102             (void)memcpy_s(cipherText + cipherTextLen, maxLen - cipherTextLen, output.data, output.len);
103         }
104         cipherTextLen += output.len;
105         if (output.data != nullptr) {
106             HcfBlobDataClearAndFree(&output);
107             output.data = nullptr;
108             output.len = 0;
109         }
110         ret = memcmp(cipherText, plainText, cipherTextLen);
111         ret =  ret || (cipherTextLen == sizeof(plainText) - 1) ? 0 : 1;
112         return ret;
113     }
114 
TestAesCipher(void)115     static void TestAesCipher(void)
116     {
117         int ret = 0;
118         uint8_t cipherText[128] = {0};
119         int cipherTextLen = 128;
120         HcfSymKeyGenerator *generator = nullptr;
121         HcfCipher *cipher = nullptr;
122         HcfSymKey *key = nullptr;
123         ret = HcfSymKeyGeneratorCreate("AES128", &generator);
124         if (ret != HCF_SUCCESS) {
125             return;
126         }
127         ret = generator->generateSymKey(generator, &key);
128         if (ret != HCF_SUCCESS) {
129             HcfObjDestroy(generator);
130             return;
131         }
132         ret = HcfCipherCreate("AES128|ECB|NoPadding", &cipher);
133         if (ret != HCF_SUCCESS) {
134             HcfObjDestroy(generator);
135             HcfObjDestroy(key);
136             return;
137         }
138 
139         (void)AesEncrypt(cipher, key, nullptr, cipherText, &cipherTextLen);
140         (void)AesDecrypt(cipher, key, nullptr, cipherText, cipherTextLen);
141         HcfObjDestroy(generator);
142         HcfObjDestroy(key);
143         HcfObjDestroy(cipher);
144     }
145 
TestRsaCipher(void)146     static void TestRsaCipher(void)
147     {
148         HcfResult res = HCF_SUCCESS;
149         uint8_t plan[] = "this is rsa cipher test!\0";
150         HcfAsyKeyGenerator *generator = nullptr;
151         res = HcfAsyKeyGeneratorCreate("RSA1024|PRIMES_2", &generator);
152         if (res != HCF_SUCCESS) {
153             return;
154         }
155         HcfKeyPair *keyPair = nullptr;
156         res = generator->generateKeyPair(generator, nullptr, &keyPair);
157         if (res != HCF_SUCCESS) {
158             HcfObjDestroy(generator);
159             return;
160         }
161 
162         HcfBlob input = { .data = plan, .len = strlen(reinterpret_cast<char *>(plan)) };
163         HcfBlob encoutput = {.data = nullptr, .len = 0};
164         HcfCipher *cipher = nullptr;
165         res = HcfCipherCreate("RSA1024|PKCS1", &cipher);
166         if (res != HCF_SUCCESS) {
167             HcfObjDestroy(generator);
168             HcfObjDestroy(keyPair);
169             return;
170         }
171 
172         (void)cipher->init(cipher, ENCRYPT_MODE, reinterpret_cast<HcfKey *>(keyPair->pubKey), nullptr);
173         (void)cipher->doFinal(cipher, &input, &encoutput);
174         HcfObjDestroy(cipher);
175 
176         HcfBlob decoutput = {.data = nullptr, .len = 0};
177         cipher = nullptr;
178         res = HcfCipherCreate("RSA1024|PKCS1", &cipher);
179         if (res != HCF_SUCCESS) {
180             HcfObjDestroy(generator);
181             HcfObjDestroy(keyPair);
182             return;
183         }
184         (void)cipher->init(cipher, DECRYPT_MODE, reinterpret_cast<HcfKey *>(keyPair->priKey), nullptr);
185         (void)cipher->doFinal(cipher, &encoutput, &decoutput);
186         HcfBlobDataClearAndFree(&encoutput);
187         HcfBlobDataClearAndFree(&decoutput);
188         HcfObjDestroy(generator);
189         HcfObjDestroy(keyPair);
190         HcfObjDestroy(cipher);
191     }
192 
HcfCipherCreateFuzzTest(const uint8_t * data,size_t size)193     bool HcfCipherCreateFuzzTest(const uint8_t* data, size_t size)
194     {
195         if (g_testFlag) {
196             TestRsaCipher();
197             TestAesCipher();
198             g_testFlag = false;
199         }
200         HcfCipher *cipher = nullptr;
201         std::string algoName(reinterpret_cast<const char *>(data), size);
202         HcfResult res = HcfCipherCreate(algoName.c_str(), &cipher);
203         if (res != HCF_SUCCESS) {
204             return false;
205         }
206         HcfObjDestroy(cipher);
207         return true;
208     }
209 }
210 
211 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)212 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
213 {
214     /* Run your code on data */
215     OHOS::HcfCipherCreateFuzzTest(data, size);
216     return 0;
217 }
218