image.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. /*
  2. * Copyright (C) 2019-2020 Alibaba Group Holding Limited
  3. */
  4. #include <errno.h>
  5. #include <string.h>
  6. #include <sys/types.h>
  7. #include <unistd.h>
  8. #include <mbedtls/rsa.h>
  9. #include <aos/kernel.h>
  10. #include <sys/stat.h>
  11. #include <fcntl.h>
  12. #include "imagef.h"
  13. int get_file_size(FILE *fp, int fd)
  14. {
  15. int file_len = 0;
  16. if (fp) {
  17. fseek(fp, 0, SEEK_END);
  18. file_len = ftell(fp);
  19. fseek(fp, 0, SEEK_SET);
  20. }
  21. if (fd >= 0) {
  22. file_len = lseek(fd, 0L, SEEK_END);
  23. lseek(fd, 0L, SEEK_SET);
  24. // FIXME: UBI return the partition length, not the file content size
  25. }
  26. // LOGD(TAG, "file_len: %d", file_len);
  27. return file_len;
  28. }
  29. uint32_t get_checksum(uint8_t *data, uint32_t length)
  30. {
  31. uint32_t cksum = 0;
  32. for (int i = 0; i < length; i++) {
  33. // if (i % 16 == 0) printf("\n");
  34. // printf("0x%02x ", *data);
  35. cksum += *data++;
  36. }
  37. // printf("\n");
  38. return cksum;
  39. }
  40. char *strdup_img_path(const char *img_name)
  41. {
  42. if (img_name == NULL) {
  43. return NULL;
  44. }
  45. char *namepath = aos_zalloc(IMG_PATH_MAX_LEN);
  46. if (namepath == NULL) {
  47. return NULL;
  48. }
  49. snprintf(namepath, IMG_PATH_MAX_LEN, "/fota_%s.bin", img_name);
  50. return namepath;
  51. }
  52. int check_kernel_partition(void)
  53. {
  54. FILE *fp;
  55. char buf[128] = {0};
  56. if ((fp = popen("fw_printenv -n boot_partition", "r")) == NULL) {
  57. return -1;
  58. }
  59. if (NULL == fgets(buf, sizeof(buf), fp)) //read line by line
  60. {
  61. pclose(fp);
  62. return -1;
  63. }
  64. pclose(fp);
  65. if (strstr(buf, "bootA"))
  66. {
  67. return 1;
  68. }
  69. else if (strstr(buf, "bootB"))
  70. {
  71. return 2;
  72. }
  73. return 0;
  74. }
  75. int check_rootfs_partition(void)
  76. {
  77. FILE *fp;
  78. char buf[128] = {0};
  79. if ((fp = popen("fw_printenv -n root_partition", "r")) == NULL) {
  80. return -1;
  81. }
  82. if (NULL == fgets(buf, sizeof(buf), fp)) //read line by line
  83. {
  84. pclose(fp);
  85. return -1;
  86. }
  87. pclose(fp);
  88. if (strstr(buf, "rootfsA"))
  89. {
  90. return 1;
  91. }
  92. else if (strstr(buf, "rootfsB"))
  93. {
  94. return 2;
  95. }
  96. return 0;
  97. }
  98. int check_partition_ab(const char *name)
  99. {
  100. FILE *fp;
  101. char buf[128] = {0};
  102. snprintf(buf, sizeof(buf) - 1, "fw_printenv -n %s_partition", name);
  103. if ((fp = popen(buf, "r")) == NULL) {
  104. return -1;
  105. }
  106. if (NULL == fgets(buf, sizeof(buf), fp)) //read line by line
  107. {
  108. pclose(fp);
  109. return -1;
  110. }
  111. pclose(fp);
  112. if (strstr(buf, "A"))
  113. {
  114. return 1;
  115. }
  116. else if (strstr(buf, "B"))
  117. {
  118. return 2;
  119. }
  120. return 0;
  121. }
  122. int get_rootfs_file_system_type(void)
  123. {
  124. static int type = 0;
  125. FILE *fp;
  126. char buf[128];
  127. if (type) {
  128. return type;
  129. }
  130. fp = fopen("/proc/cmdline", "r");
  131. if (fp == NULL) {
  132. return -1;
  133. }
  134. if (fgets(buf, sizeof(buf), fp) == NULL) {
  135. fclose(fp);
  136. return -1;
  137. }
  138. fclose(fp);
  139. if (strstr(buf, "rootfstype=ext4")) {
  140. type = 2;
  141. } else {
  142. type = 1;
  143. }
  144. return type;
  145. }
  146. int mbed_sha1_rsa_verify(uint8_t *pub_key, uint32_t key_size, uint8_t *hash, uint8_t *sig)
  147. {
  148. int ret;
  149. mbedtls_rsa_context rsa;
  150. // for (int i = 0; i < 128; i++) {
  151. // if (i % 16 == 0) printf("\n");
  152. // printf("0x%02x ", sig[i]);
  153. // }
  154. // printf("\n");
  155. mbedtls_rsa_init(&rsa, MBEDTLS_RSA_PKCS_V15, 0);
  156. mbedtls_mpi_read_binary(&rsa.N, pub_key, key_size);
  157. rsa.len = mbedtls_mpi_size(&rsa.N);
  158. mbedtls_mpi_read_string(&rsa.E, 16, "10001");
  159. ret = mbedtls_rsa_pkcs1_verify(&rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 0, hash, sig);
  160. if (ret != 0) {
  161. printf("rsa verify failed!!, ret:-0x%04x\n", ret);
  162. goto exit;
  163. }
  164. exit:
  165. mbedtls_rsa_free(&rsa);
  166. return ret;
  167. }
  168. int mbed_sha256_rsa_verify(uint8_t *pub_key, uint32_t key_size, uint8_t *hash, uint8_t *sig)
  169. {
  170. int ret;
  171. mbedtls_rsa_context rsa;
  172. mbedtls_rsa_init(&rsa, MBEDTLS_RSA_PKCS_V15, 0);
  173. mbedtls_mpi_read_binary(&rsa.N, pub_key, key_size);
  174. rsa.len = mbedtls_mpi_size(&rsa.N);
  175. mbedtls_mpi_read_string(&rsa.E, 16, "10001");
  176. ret = mbedtls_rsa_pkcs1_verify(&rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA256, 0, hash, sig);
  177. if (ret != 0) {
  178. printf("rsa verify failed!!, ret:-0x%04x\n", ret);
  179. goto exit;
  180. }
  181. exit:
  182. mbedtls_rsa_free(&rsa);
  183. return ret;
  184. }
  185. int set_rollback_env_param(int limit_c)
  186. {
  187. int ret;
  188. char cmd[64] = {0};
  189. snprintf(cmd, sizeof(cmd), "fw_setenv bootlimit %d", limit_c);
  190. ret = system(cmd);
  191. ret |= system("fw_setenv bootcount 0");
  192. ret |= system("fw_setenv upgrade_available 1");
  193. return ret;
  194. }
  195. int fw_setenv_run_script(const char *cmd)
  196. {
  197. FILE *fp;
  198. fp = popen("fw_setenv -s -", "w");
  199. if(fp != NULL) {
  200. if (fwrite(cmd, strlen(cmd), 1, fp) != strlen(cmd)) {
  201. pclose(fp);
  202. return -1;
  203. }
  204. pclose(fp);
  205. return 0;
  206. }
  207. return -1;
  208. }
  209. // return value: 0--do not need upgrade; 1--upgrade failed, rollback already; 2--upgrade ok.
  210. int set_fota_success_param(void)
  211. {
  212. FILE *fp;
  213. int var = 0;
  214. int ret = 0;
  215. int bootlimit = 0, bootcount = 0;
  216. char buf[64] = {0}, cmd[128];
  217. if ((fp = popen("fw_printenv -n upgrade_available 2>/dev/null", "r")) == NULL) {
  218. return -1;
  219. }
  220. *buf = 0;
  221. fgets(buf, sizeof(buf), fp); //read line by line
  222. pclose(fp);
  223. if (strstr(buf, "0") || (strlen(buf) == 0))
  224. {
  225. return 0;
  226. }
  227. *buf = 0;
  228. fp = popen("fw_printenv -n bootlimit", "r");
  229. fgets(buf, sizeof(buf), fp);
  230. pclose(fp);
  231. if (strlen(buf)) {
  232. bootlimit = atoi(buf);
  233. }
  234. *buf = 0;
  235. fp = popen("fw_printenv -n bootcount", "r");
  236. fgets(buf, sizeof(buf), fp);
  237. pclose(fp);
  238. if (strlen(buf)) {
  239. bootcount = atoi(buf);
  240. }
  241. if (bootcount > bootlimit) {
  242. // FOTA boot failed, rollback
  243. if (FILE_SYSTEM_IS_UBI()) {
  244. fp = popen("fw_printenv -n boot_partition_alt", "r");
  245. fgets(buf, sizeof(buf), fp);
  246. pclose(fp);
  247. snprintf(cmd, sizeof(cmd), "fw_setenv boot_partition %s", buf);
  248. ret |= system(cmd);
  249. fp = popen("fw_printenv -n root_partition_alt", "r");
  250. fgets(buf, sizeof(buf), fp);
  251. pclose(fp);
  252. snprintf(cmd, sizeof(cmd), "fw_setenv root_partition %s", buf);
  253. ret |= system(cmd);
  254. }
  255. var = 1;
  256. } else {
  257. if (FILE_SYSTEM_IS_UBI()) {
  258. fp = popen("fw_printenv -n boot_partition", "r");
  259. fgets(buf, sizeof(buf), fp);
  260. pclose(fp);
  261. snprintf(cmd, sizeof(cmd), "fw_setenv boot_partition_alt %s", buf);
  262. ret |= system(cmd);
  263. fp = popen("fw_printenv -n root_partition", "r");
  264. fgets(buf, sizeof(buf), fp);
  265. pclose(fp);
  266. snprintf(cmd, sizeof(cmd), "fw_setenv root_partition_alt %s", buf);
  267. ret |= system(cmd);
  268. if (buf[strlen(buf)-1] < '0') {
  269. buf[strlen(buf)-1] = 0;
  270. }
  271. if (0 == (set_ubivol_cmd(buf, cmd, sizeof(cmd)))) {
  272. ret |= system(cmd);
  273. }
  274. }
  275. var = 2;
  276. }
  277. fw_setenv_run_script("bootlimit 0\n" \
  278. "bootcount 0\n" \
  279. "upgrade_available 0\n" \
  280. "boot_partition_alt\n" \
  281. "root_partition_alt\n");
  282. return var;
  283. }
  284. int set_ubivol_cmd(const char* vol_name, char *o_cmd, int len)
  285. {
  286. FILE *fp;
  287. char buf[64], cmd[128];
  288. int vol_cnt = 0, i;
  289. if (!FILE_SYSTEM_IS_UBI()) {
  290. return 0;
  291. }
  292. if ((fp = popen("ls -l /dev/ubi0_* | wc -l", "r")) == NULL) {
  293. return -1;
  294. }
  295. fgets(buf, sizeof(buf), fp);
  296. pclose(fp);
  297. if (strlen(buf)) {
  298. vol_cnt = atoi(buf);
  299. }
  300. vol_cnt = vol_cnt > 1 ? vol_cnt : 1;
  301. o_cmd[0] = 0;
  302. for (i = vol_cnt - 1; i >= 0; i--) {
  303. snprintf(cmd, sizeof(cmd), "ubinfo /dev/ubi0_%d | grep %s | wc -l", i, vol_name);
  304. if ((fp = popen(cmd, "r")) == NULL) {
  305. return -1;
  306. }
  307. fgets(buf, sizeof(buf), fp);
  308. pclose(fp);
  309. if (strstr(buf, "1")) {
  310. snprintf(o_cmd, len, "fw_setenv nand_root_alt /dev/ubiblock0_%d", i);
  311. break;
  312. }
  313. }
  314. if (i < 0) {
  315. return -1;
  316. }
  317. // LOGD(TAG, "cmd:%s", o_cmd);
  318. return 0;
  319. }