1 /*
2 * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <openssl/md5.h>
18 #include <stdio.h>
19 #include <unistd.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <fcntl.h>
23 #include <string.h>
24 #include <stdlib.h>
25 #include <errno.h>
26 #include <stdbool.h>
27 #include "log.h"
28 #include "rktools.h"
29 #include "../mtdutils/mtdutils.h"
30
31
32 #define TMP_MD5SUM_NAME "/tmp/.tmp_md5sum"
33
checkdata_mtd(const char * dest_path,unsigned char * out_md5sum,long long offset,long long checkSize)34 bool checkdata_mtd(const char *dest_path, unsigned char* out_md5sum, long long offset, long long checkSize)
35 {
36
37 char nanddump_cmd[256] = {0};
38 unsigned char buf[33] = {0};
39 unsigned char md5sum[16];
40
41 LOGI( "[%s:%d] offset [%lld] checksize [%lld] \n", __func__, __LINE__, offset, checkSize );
42
43 memset(nanddump_cmd, 0, sizeof(nanddump_cmd) / sizeof(nanddump_cmd[0]));
44 sprintf(nanddump_cmd, "nanddump --bb=skipbad -l %lld -s %lld %s | md5sum > %s",
45 checkSize, offset, dest_path, TMP_MD5SUM_NAME);
46 if (system(nanddump_cmd) == -1) {
47 LOGE("system cmd error");
48 return -1;
49 }
50 int dest_fd = open(TMP_MD5SUM_NAME, O_RDONLY );
51 if (dest_fd == 0) {
52 LOGE("open file failed %s", TMP_MD5SUM_NAME);
53 return -1;
54 }
55
56 if (read(dest_fd, buf, 32) == -1) {
57 close(dest_fd);
58 LOGE("(%s:%d) read error: %s.\n", __func__, __LINE__, strerror(errno));
59 return -2;
60 }
61
62 printf("\n");
63 buf[32] = '\0';
64 LOGI("read new md5: [%s]\n", buf);
65
66 unsigned char md5sum_tmp[32];
67 for ( int ii = 0; ii < 32; ii += 2) {
68 sscanf((char *)(buf + ii), "%02hhx", &md5sum_tmp[ii]);
69 }
70
71 for ( int ii = 0, j = 0; ii < 32; ii += 2 ) {
72 // printf ( "%d = %02x\n", ii, md5sum_tmp[ii] );
73 md5sum[j] = md5sum_tmp[ii];
74 j++;
75 }
76
77 LOGI("new md5:");
78 for (int i = 0; i < 16; i++) {
79 printf("%02x", md5sum[i]);
80 }
81 printf("\n");
82 //change
83 if (out_md5sum != NULL) {
84 memset(out_md5sum, 0, 16);
85 memcpy(out_md5sum, md5sum, 16);
86 }
87
88 close(dest_fd);
89 LOGI("MD5Check is ok of %s\n", dest_path);
90 return 0;
91 }
92
checkdata(const char * dest_path,unsigned char * out_md5sum,long long offset,long long checkSize)93 bool checkdata(const char *dest_path, unsigned char *out_md5sum, long long offset, long long checkSize)
94 {
95 MD5_CTX ctx;
96 unsigned char md5sum[16];
97 char buffer[512];
98 int len = 0;
99 int ret;
100
101 FILE *fp = fopen(dest_path, "rb");
102 if (fp == NULL) {
103 LOGE("open file failed %s", dest_path);
104 return -1;
105 }
106
107 ret = fseeko64(fp, offset, SEEK_SET);
108 if (ret < 0) {
109 LOGE("%s:%d fseeko64 fail", __func__, __LINE__);
110 return false;
111 }
112
113 MD5_Init(&ctx);
114
115 long long readSize = 0;
116 int step = 512;
117 while (checkSize > 0) {
118 readSize = checkSize > step ? step : checkSize;
119 if (fread(buffer, 1, readSize, fp) != readSize) {
120 LOGE("fread error.\n");
121 return false;
122 }
123 checkSize = checkSize - readSize;
124 MD5_Update(&ctx, buffer, readSize);
125 memset(buffer, 0, sizeof(buffer));
126 }
127 MD5_Final(md5sum, &ctx);
128 fclose(fp);
129
130 LOGI("new md5:");
131 for (int i = 0; i < 16; i++) {
132 printf("%02x", md5sum[i]);
133 }
134 printf("\n");
135 //change
136 if (out_md5sum != NULL) {
137 memset(out_md5sum, 0, 16);
138 memcpy(out_md5sum, md5sum, 16);
139 }
140 LOGI("MD5Check is ok of %s\n", dest_path);
141 return 0;
142 }
143
comparefile(const char * dest_path,const char * source_path,long long dest_offset,long long source_offset,long long checkSize)144 bool comparefile(const char *dest_path, const char *source_path, long long dest_offset, long long source_offset, long long checkSize)
145 {
146 unsigned char md5sum_source[16];
147 unsigned char md5sum_dest[16];
148 if (isMtdDevice()) {
149 checkdata_mtd(dest_path, md5sum_dest, dest_offset, checkSize);
150 } else {
151 checkdata(dest_path, md5sum_dest, dest_offset, checkSize);
152 }
153 checkdata(source_path, md5sum_source, source_offset, checkSize);
154 for (int i = 0; i < 16; i++) {
155 if (md5sum_dest[i] != md5sum_source[i]) {
156 LOGE("MD5Check is error of %s\n", dest_path);
157 return false;
158 }
159 }
160 return true;
161 }
162
compareMd5sum(const char * dest_path,unsigned char * source_md5sum,long long offset,long long checkSize)163 bool compareMd5sum(const char *dest_path, unsigned char *source_md5sum, long long offset, long long checkSize)
164 {
165 unsigned char md5sum[16];
166
167 checkdata(dest_path, md5sum, offset, checkSize);
168
169 unsigned char tmp[16][2] = {
170 0x30, 0x00,
171 0x31, 0x01,
172 0x32, 0x02,
173 0x33, 0x03,
174 0x34, 0x04,
175 0x35, 0x05,
176 0x36, 0x06,
177 0x37, 0x07,
178 0x38, 0x08,
179 0x39, 0x09,
180 0x61, 0x0a,
181 0x62, 0x0b,
182 0x63, 0x0c,
183 0x64, 0x0d,
184 0x65, 0x0e,
185 0x66, 0x0f,
186 };
187 for (int i = 0; i < 32; i = i + 2) {
188 for (int j = 0; j < 16; j++) {
189 if (tmp[j][1] == (md5sum[i / 2] >> 4)) {
190 if (source_md5sum[i] != tmp[j][0]) {
191 LOGE("MD5Check is error of %s\n", dest_path);
192 return false;
193 }
194 }
195 if (tmp[j][1] == (md5sum[i / 2] & 0x0f)) {
196 if (source_md5sum[i + 1] != tmp[j][0]) {
197 LOGE("MD5Check is error of %s\n", dest_path);
198 return false;
199 }
200 }
201 }
202 }
203 return true;
204 }
205