1 /*
2  * Copyright (c) 2021 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 "hota_verify.h"
17 
18 #include <securec.h>
19 #include "app_rsa.h"
20 #include "app_sha256.h"
21 #include "hal_hota_board.h"
22 
23 
24 static uint8 g_hash[HASH_LENGTH] = {0};
25 
26 static AppSha256Context g_sha256 = { 0 }; /* hash tmp var */
27 
HotaHashInit(void)28 void HotaHashInit(void)
29 {
30     AppSha256Init(&g_sha256);
31     // Init the hash value of data
32     if (memset_s(g_hash, HASH_LENGTH, 0, HASH_LENGTH) != EOK) {
33         return;
34     }
35 
36     return;
37 }
38 
HotaHashCalc(const uint8 * buffer,uint32 length)39 void HotaHashCalc(const uint8 *buffer, uint32 length)
40 {
41     if (buffer == NULL) {
42         printf("HashCalc param in null!\r\n");
43         return;
44     }
45 
46     AppSha256Update(&g_sha256, buffer, length);
47     return;
48 }
49 
HotaGetHash(uint8 * buffer,uint32 length)50 int32 HotaGetHash(uint8 *buffer, uint32 length)
51 {
52     if (buffer == NULL) {
53         printf("GetHash param in null!\r\n");
54         return OHOS_FAILURE;
55     }
56 
57     if (memset_s(buffer, length, 0, length) != EOK) {
58         return OHOS_FAILURE;
59     }
60 
61     if (length >= HASH_LENGTH) {
62         // Calc the last hash, and save it
63         AppSha256Finish(&g_sha256, g_hash);
64         if (memcpy_s(buffer, HASH_LENGTH, g_hash, HASH_LENGTH) != EOK) {
65             return OHOS_FAILURE;
66         }
67         return OHOS_SUCCESS;
68     } else {
69         printf("GetHash len illegal!\r\n");
70         return OHOS_FAILURE;
71     }
72 }
73 
HotaCalcImageHash(uint8 * dataAddr,uint32 dataLen,uint8 * hash,uint32 hashLen)74 static int32 HotaCalcImageHash(uint8 *dataAddr, uint32 dataLen, uint8 *hash, uint32 hashLen)
75 {
76     AppSha256Context sha256;
77     uint32 count;
78 
79     if ((dataAddr == NULL) || (hash == NULL) || (dataLen == 0) || (hashLen < HASH_LENGTH)) {
80         printf("HotaCalcImageHash param is illegal.\r\n");
81         return OHOS_FAILURE;
82     }
83 
84     uint8 *databuf = dataAddr;
85     if (memset_s(hash, hashLen, 0, hashLen) != EOK) {
86         printf("HotaCalcImageHash memset_s hash failed.\r\n");
87         return OHOS_FAILURE;
88     }
89     AppSha256Init(&sha256);
90 
91     while (dataLen > 0) {
92         count = (dataLen > BUFFR_LENGTH) ? BUFFR_LENGTH : dataLen;
93         AppSha256Update(&sha256, databuf, count);
94         dataLen -= count;
95         databuf += count;
96     }
97     // Calc Final hash
98     AppSha256Finish(&sha256, hash);
99 
100     return OHOS_SUCCESS;
101 }
102 
HotaSignVerifyByHash(const uint8 * hash,uint32 hashLen,const uint8 * imageSign,uint32 signLen)103 static int32 HotaSignVerifyByHash(const uint8 *hash, uint32 hashLen, const uint8 *imageSign, uint32 signLen)
104 {
105     AppRsaContext rsa;
106     uint32 length = 0;
107     if ((hash == NULL) || (imageSign == NULL)) {
108         return OHOS_FAILURE;
109     }
110 
111     AppRsaInit(&rsa);
112     uint8 *keyBuf = HotaGetPubKey(&length);
113     if (keyBuf == NULL) {
114         return OHOS_FAILURE;
115     }
116 
117     int ret = AppRsaDecodePublicKey(&rsa, keyBuf, length);
118     if (ret != 0) {
119         return OHOS_FAILURE;
120     }
121 
122     ret = AppVerifyData(&rsa, hash, hashLen, imageSign, signLen);
123     AppRsaFree(&rsa);
124     if (ret < 0) {
125         printf("App verify failed.\r\n");
126         return OHOS_FAILURE;
127     }
128 
129     return OHOS_SUCCESS;
130 }
131 
HotaSignVerify(uint8 * image,uint32 imgLen,uint8 * imageSign,uint32 signLen)132 int32 HotaSignVerify(uint8 *image, uint32 imgLen, uint8 *imageSign, uint32 signLen)
133 {
134     if ((image == NULL) || (imageSign == NULL)) {
135         printf("SignVerify param in illegal, len %u!\r\n", signLen);
136         return OHOS_FAILURE;
137     }
138 
139     uint8 imageHashLocal[HASH_LENGTH] = {0};
140     if (HotaCalcImageHash(image, imgLen, imageHashLocal, HASH_LENGTH) != OHOS_SUCCESS) {
141         printf("HotaCalcImageHash fail!\r\n");
142         return OHOS_FAILURE;
143     }
144 
145     // Use local hash of data to verify the sign
146     int ret = HotaSignVerifyByHash(imageHashLocal, HASH_LENGTH, imageSign, signLen);
147     if (ret != OHOS_SUCCESS) {
148         printf("SignVerify fail!\r\n");
149         return OHOS_FAILURE;
150     }
151 
152     return OHOS_SUCCESS;
153 }
154 
HotaGetPubKey(uint32 * length)155 uint8 *HotaGetPubKey(uint32 *length)
156 {
157     return HotaHalGetPubKey(length);
158 }
159