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