xref: /OK3568_Linux_fs/external/recovery/update_engine/md5sum.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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