1 /*
2 * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3 */
4
5 #include <stdio.h>
6 #include <string.h>
7 #include <stdlib.h>
8 #include <unistd.h>
9 #include <errno.h>
10 #include <fcntl.h>
11 #include "ota_log.h"
12 #include "ota_import.h"
13 #include "ota_hal_os.h"
14 #include "ota_hal_digest.h"
15 #include "ota_hal.h"
16 #include <aos/vfs.h>
17
18 static ota_hash_ctx_t hash_ctx = {0};
19 static unsigned short upg_flag = 0;
20 static unsigned char is_header = 0;
21 #ifdef OTA_CONFIG_LOCAL_RSA
22 static unsigned int valid_image_len = 0;
23 static unsigned int calculated_len = 0;
24 #endif
25
ota_int(ota_boot_param_t * param)26 int ota_int(ota_boot_param_t *param)
27 {
28 int ret = 0;
29 if (param == NULL) {
30 return OTA_UPGRADE_PARAM_FAIL;
31 }
32 is_header = 0;
33 upg_flag = 0;
34 #ifdef OTA_CONFIG_LOCAL_RSA
35 calculated_len = 0;
36 valid_image_len = param->len - sizeof(ota_image_info_t) - sizeof(ota_sign_info_t);
37 #endif
38 ret = ota_hal_init(param);
39 if (ret == 0) {
40 ret = ota_hash_init(&hash_ctx, param->hash_type);
41 }
42 OTA_LOG_I("ota init ret = %d\r\n", ret);
43 return ret;
44 }
45
ota_write(unsigned int * off,char * in_buf,unsigned int in_buf_len)46 int ota_write(unsigned int *off, char *in_buf, unsigned int in_buf_len)
47 {
48 int ret = 0;
49 if ((*off == 0) && (is_header == 0)) {
50 unsigned char xz_header[6] = { 0xFD, '7', 'z', 'X', 'Z', 0x00 };
51 if (memcmp(in_buf, "BSDIFF40", 8) == 0) {
52 upg_flag = OTA_UPGRADE_DIFF;
53 } else if (memcmp(in_buf, xz_header, 6) == 0) {
54 upg_flag = OTA_UPGRADE_XZ;
55 }
56 OTA_LOG_I("ota header:0x%x\n", upg_flag);
57 is_header = 1;
58 }
59 ret = ota_hal_write(off, in_buf, in_buf_len);
60 if (ret >= 0) {
61 #ifdef OTA_CONFIG_LOCAL_RSA
62 if (calculated_len <= valid_image_len) {
63 ota_hash_ctx_t tmp_ctx = hash_ctx;
64 unsigned int tmp_len = 0;
65 ((calculated_len + in_buf_len) <= valid_image_len) ? (tmp_len = in_buf_len) :
66 (tmp_len = valid_image_len - calculated_len);
67 ret = ota_hash_update(&hash_ctx, (const unsigned char *)in_buf, tmp_len);
68 if (ret >= 0) {
69 calculated_len += in_buf_len;
70 } else {
71 hash_ctx = tmp_ctx;
72 }
73 }
74 #else
75 ret = ota_hash_update(&hash_ctx, (const unsigned char *)in_buf, in_buf_len);
76 #endif
77 }
78 return ret;
79 }
80
ota_read(unsigned int * off,char * out_buf,unsigned int out_buf_len)81 int ota_read(unsigned int *off, char *out_buf, unsigned int out_buf_len)
82 {
83 int ret = 0;
84 ret = ota_hal_read(off, out_buf, out_buf_len);
85 return ret;
86 }
87
ota_clear()88 int ota_clear()
89 {
90 is_header = 0;
91 upg_flag = 0;
92 return ota_clear_paramters();
93 }
94
ota_verify(ota_boot_param_t * param)95 int ota_verify(ota_boot_param_t *param)
96 {
97 int ret = OTA_UPGRADE_SET_BOOT_FAIL;
98 unsigned char hash[32] = {0};
99 char dst_hash[65] = {0};
100 if (param == NULL) {
101 return ret;
102 }
103 is_header = 0;
104 if (upg_flag != 0) {
105 param->upg_flag = upg_flag;
106 } else if (param->upg_flag == 0) {
107 param->upg_flag = OTA_UPGRADE_ALL;
108 }
109 memset(hash, 0x00, sizeof(hash));
110 ret = ota_hash_final(&hash_ctx, hash);
111 if (ret == 0) {
112 ret = ota_hex2str(dst_hash, hash, sizeof(dst_hash), sizeof(hash));
113 if (ret == 0) {
114 ret = ota_check_hash(param->hash_type, param->hash, (char *)dst_hash);
115 if (ret < 0) {
116 OTA_LOG_E("ota verify hash failed!");
117 return ret;
118 }
119 /* verify RSA signature */
120 #if OTA_CONFIG_LOCAL_RSA
121 ret = ota_verify_rsa((unsigned char *)param->sign, (const char *)dst_hash, param->hash_type);
122 if (ret < 0) {
123 ret = OTA_VERIFY_RSA_FAIL;
124 return ret;
125 }
126 #else
127 if (strlen(param->sign) > 0) {
128 ret = ota_verify_rsa((unsigned char *)param->sign, (const char *)dst_hash, param->hash_type);
129 if (ret < 0) {
130 ret = OTA_VERIFY_RSA_FAIL;
131 return ret;
132 }
133 }
134 #endif
135 /* verify image */
136 #if !defined CONFIG_PING_PONG_OTA
137 if ((param->upg_flag != OTA_UPGRADE_DIFF) && (param->upg_flag != OTA_UPGRADE_CUST)) {
138 ret = ota_check_image(param->len);
139 if (ret < 0) {
140 ret = OTA_VERIFY_IMAGE_FAIL;
141 }
142 }
143 #endif
144 }
145 }
146 OTA_LOG_I("ota boot finish ret:%d crc:0x%04x", ret, param->crc);
147 return ret;
148 }
149
ota_verify_fsfile(ota_boot_param_t * param,char * file_path)150 int ota_verify_fsfile(ota_boot_param_t *param, char *file_path)
151 {
152 int fd = -1;
153 int ret = OTA_UPGRADE_SET_BOOT_FAIL;
154 unsigned char hash[32] = {0};
155 char dst_hash[65] = {0};
156 char tmp_buf[128] = {0};
157 unsigned int offset = 0;
158 unsigned int read_len = 0;
159 ota_hash_ctx_t tmp_hash_ctx;
160 if ((param == NULL) || (file_path == NULL)) {
161 return ret;
162 }
163 memset(hash, 0x00, sizeof(hash));
164 ret = ota_hash_init(&tmp_hash_ctx, param->hash_type);
165 if (ret < 0) {
166 OTA_LOG_E("subdev fs file hash init failed\n");
167 return ret;
168 }
169 fd = ota_fopen(file_path, O_RDONLY);
170 if (fd < 0) {
171 ret = OTA_UPGRADE_SET_BOOT_FAIL;
172 OTA_LOG_E("open %s failed\n", file_path);
173 return ret;
174 }
175 OTA_LOG_I("fs size = %d\n", param->len);
176 while (offset < param->len) {
177 (param->len - offset >= sizeof(tmp_buf)) ? (read_len = sizeof(tmp_buf)) : (read_len = param->len - offset);
178 ret = ota_fread(fd, (void *)tmp_buf, read_len);
179 if (ret < 0) {
180 OTA_LOG_E("verify fs file read file failed\r\n");
181 ret = OTA_VERIFY_IMAGE_FAIL;
182 break;
183 }
184 ret = ota_hash_update(&tmp_hash_ctx, (const unsigned char *)tmp_buf, read_len);
185 if (ret < 0) {
186 break;
187 }
188 offset += read_len;
189 ota_msleep(5);
190 }
191 if (fd >= 0) {
192 (void)ota_fclose(fd);
193 }
194 if (ret < 0) {
195 OTA_LOG_E("get fs file hash value failed\n");
196 return ret;
197 }
198 ret = ota_hash_final(&tmp_hash_ctx, hash);
199 if (ret == 0) {
200 ret = ota_hex2str(dst_hash, hash, sizeof(dst_hash), sizeof(hash));
201 if (ret == 0) {
202 ret = ota_check_hash(param->hash_type, param->hash, (char *)dst_hash);
203 if (ret < 0) {
204 OTA_LOG_E("ota verify hash failed!");
205 return ret;
206 }
207 /* verify RSA signature */
208 #if OTA_CONFIG_LOCAL_RSA
209 ret = ota_verify_rsa((unsigned char *)param->sign, (const char *)dst_hash, param->hash_type);
210 if (ret < 0) {
211 ret = OTA_VERIFY_RSA_FAIL;
212 return ret;
213 }
214 #else
215 if (strlen(param->sign) > 0) {
216 ret = ota_verify_rsa((unsigned char *)param->sign, (const char*)dst_hash, param->hash_type);
217 if (ret < 0) {
218 ret = OTA_VERIFY_RSA_FAIL;
219 return ret;
220 }
221 }
222 #endif
223 }
224 }
225 OTA_LOG_I("verfiy fs over ret:%d\n", ret);
226 return ret;
227 }