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 "hksrkc_fuzzer.h"
17
18 #include "hks_ability.h"
19 #include "hks_api.h"
20 #include "hks_log.h"
21 #include "hks_mem.h"
22 #include "hks_param.h"
23 #include "hks_type_inner.h"
24 #include "hks_rkc.h"
25 #include "hks_rkc_rw.c"
26 #include "hks_rkc_v1.c"
27
28 #include "cstring"
29 #include "unistd.h"
30 #include "securec.h"
31
32 namespace OHOS {
33 namespace Security {
34 namespace Hks {
35
TestGetMkFromOldKsfFile(const HksBlob * oldKsfBlob,const uint8_t mkPlaintext[HKS_RKC_MK_LEN])36 static void TestGetMkFromOldKsfFile(const HksBlob *oldKsfBlob, const uint8_t mkPlaintext[HKS_RKC_MK_LEN])
37 {
38 // step1. parse old ksf file
39 struct HksRkcKsfDataV1 ksfDataV1 = { 0 };
40 int32_t ret = RkcExtractKsfBufV1(oldKsfBlob, &ksfDataV1);
41
42 // step2. decrypt mk
43 uint8_t mk[HKS_RKC_MK_LEN] = { 0 };
44 struct HksBlob tempMkBlob = { HKS_RKC_MK_LEN, mk };
45 struct HksBlob cipherTextBlob = { sizeof(ksfDataV1.ksfDataMk.mkCiphertext), ksfDataV1.ksfDataMk.mkCiphertext };
46 ret = RkcMkCryptV1(&ksfDataV1, &tempMkBlob, &cipherTextBlob, false);
47 HksMemCmp(mkPlaintext, tempMkBlob.data, HKS_RKC_MK_LEN);
48 }
49
TestStoreNewKsfFile(HksBlob * rkcBlob,HksBlob * mkBlob,const uint8_t mkPlaintext[HKS_RKC_MK_LEN])50 static void TestStoreNewKsfFile(HksBlob *rkcBlob, HksBlob *mkBlob, const uint8_t mkPlaintext[HKS_RKC_MK_LEN])
51 {
52 // step3. create new rkc material
53 struct HksKsfDataRkcWithVer newRkc = { 0 };
54 int32_t ret = FillKsfDataRkcWithVer(&newRkc);
55
56 // step4. encrypt mk with new rkc
57 struct HksKsfDataMkWithVer newMk = { 0 };
58 FillKsfDataMkWithVer(&newMk);
59
60 struct HksBlob tempMkBlob = { HKS_RKC_MK_LEN, (uint8_t *)mkPlaintext };
61 struct HksBlob cipherTextBlob = { sizeof(newMk.ksfDataMk.mkCiphertext), newMk.ksfDataMk.mkCiphertext };
62 ret = RkcMkCrypt(&(newRkc.ksfDataRkc), &(newMk.ksfDataMk), &tempMkBlob, &cipherTextBlob, true);
63
64 // step5. store new rkc and mk file
65 ret = FillKsfBufRkc(&newRkc, rkcBlob);
66 ret = FillKsfBufMk(&newMk, mkBlob);
67 }
68
TestGetMkFromNewKsfFile(const HksBlob * rkcBlob,const HksBlob * mkBlob,const uint8_t mkPlaintext[HKS_RKC_MK_LEN])69 static void TestGetMkFromNewKsfFile(const HksBlob *rkcBlob, const HksBlob *mkBlob,
70 const uint8_t mkPlaintext[HKS_RKC_MK_LEN])
71 {
72 // step6. read new rkc and mk file
73 struct HksKsfDataRkcWithVer newRkc = { 0 };
74 int32_t ret = ExtractKsfBufRkc(rkcBlob, &newRkc);
75
76 struct HksKsfDataMkWithVer newMk = { 0 };
77 ret = ExtractKsfBufMk(mkBlob, &newMk);
78
79 // step7. decrypt mk
80 uint8_t mk[HKS_RKC_MK_LEN] = { 0 };
81 struct HksBlob tempMkBlob = { HKS_RKC_MK_LEN, mk };
82 struct HksBlob cipherTextBlob = { sizeof(newMk.ksfDataMk.mkCiphertext), newMk.ksfDataMk.mkCiphertext };
83 ret = RkcMkCrypt(&newRkc.ksfDataRkc, &newMk.ksfDataMk, &tempMkBlob, &cipherTextBlob, false);
84 HksMemCmp(mkPlaintext, tempMkBlob.data, HKS_RKC_MK_LEN);
85 }
86
87 /**
88 * @tc.name: HksUpgradeRkcTest.HksUpgradeRkcTest001
89 * @tc.desc: rewrite rkc&mk file and check mkPlaintext's consistency
90 * @tc.type: FUNC
91 */
HksUpgradeRkcTest001()92 static void HksUpgradeRkcTest001()
93 {
94 uint8_t oldKsfFile[] = {
95 0x5f, 0x64, 0x97, 0x8d, 0x19, 0x4f, 0x89, 0xcf, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
96 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x95, 0x28, 0x4a, 0xca, 0x82, 0xbf, 0xe7,
97 0xb2, 0x9f, 0x6b, 0xa6, 0x4c, 0x92, 0x60, 0x43, 0xb7, 0x2d, 0xda, 0x28, 0xae, 0x91, 0x59, 0xa8,
98 0x7c, 0x02, 0x5a, 0x89, 0x92, 0x9e, 0x2f, 0x38, 0xeb, 0x7b, 0x0f, 0x71, 0xe3, 0xd8, 0x8a, 0x54,
99 0x1f, 0x92, 0x6a, 0x96, 0xf0, 0x79, 0xf5, 0xde, 0x35, 0x2f, 0x04, 0x02, 0x69, 0x0f, 0x51, 0x38,
100 0x95, 0xff, 0xdd, 0x98, 0x40, 0xd7, 0x32, 0x08, 0x01, 0x00, 0x00, 0x00, 0xf8, 0x93, 0xa4, 0x81,
101 0x47, 0x5a, 0xaf, 0x91, 0x50, 0x5a, 0x48, 0x1b, 0xea, 0xab, 0x50, 0x76, 0x65, 0xc1, 0x6d, 0x9e,
102 0xa6, 0xe4, 0x28, 0x80, 0xe0, 0xcc, 0x28, 0x9a, 0x89, 0xa2, 0x46, 0x1b, 0x01, 0x00, 0x00, 0x00,
103 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x95, 0x62, 0x5a, 0x85, 0x0e, 0xc8,
105 0xb9, 0xc3, 0x3b, 0x4f, 0xb9, 0xe7, 0xbf, 0x6a, 0x4e, 0x88, 0xfb, 0x9e, 0xc5, 0x3e, 0x5a, 0x05,
106 0x2a, 0x4d, 0xb3, 0x1f, 0xac, 0xf1, 0xe7, 0x7f, 0x6e, 0x86, 0x69, 0xb5, 0xd9, 0x6f, 0x27, 0xc4,
107 0xab, 0x9f, 0xbe, 0x0d, 0x86, 0xbd, 0x9c, 0x3f, 0x24, 0xce, 0x39, 0x4d, 0xab, 0xd5, 0x5c, 0x23,
108 0xbc, 0x3e, 0x8c, 0xf3, 0xe7, 0xe5, 0x41, 0x3d, 0xb7, 0xba, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
109 0x00, 0x00, 0x65, 0xfe, 0xe7, 0x25, 0xf8, 0x08, 0x3e, 0x33, 0xa5, 0x1e, 0x25, 0x31, 0x4c, 0xf0,
110 0xe2, 0x59, 0xc9, 0x56, 0xa9, 0xf1, 0xb9, 0xa3, 0xce, 0xe8, 0xbd, 0x50, 0xad, 0xa6, 0x46, 0x5e,
111 0x42, 0xea,
112 };
113
114 uint8_t mkPlaintext[] = {
115 0x33, 0x45, 0x73, 0xfb, 0x7f, 0x1a, 0x45, 0xb5, 0x47, 0xcf, 0x86, 0xe6, 0x3b, 0x55, 0xf2, 0x2f,
116 0x9e, 0x8d, 0x22, 0x3f, 0x46, 0x8c, 0x3b, 0x7e, 0x3d, 0xb7, 0xb3, 0x4d, 0x97, 0x2b, 0xd7, 0x0c,
117 };
118
119 HksBlob oldKsfBlob = { sizeof(oldKsfFile), oldKsfFile };
120 TestGetMkFromOldKsfFile(&oldKsfBlob, mkPlaintext);
121
122 uint8_t rkcFile[HKS_KSF_BUF_LEN] = { 0 };
123 struct HksBlob rkcBlob = { HKS_KSF_BUF_LEN, rkcFile };
124 uint8_t mkFile[HKS_KSF_BUF_LEN] = { 0 };
125 struct HksBlob mkBlob = { HKS_KSF_BUF_LEN, mkFile };
126 TestStoreNewKsfFile(&rkcBlob, &mkBlob, mkPlaintext);
127
128 TestGetMkFromNewKsfFile(&rkcBlob, &mkBlob, mkPlaintext);
129 }
130 }
131 }
132 }
133
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)134 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
135 {
136 (void)data;
137 (void)size;
138 OHOS::Security::Hks::HksUpgradeRkcTest001();
139 return 0;
140 }
141