xref: /OK3568_Linux_fs/external/rkupdate/RKImage.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 #include "RKImage.h"
2 #include "MD5Checksum.h"
3 
4 extern int IsRK3308_Platform();
5 extern int Compatible_rk3308bs_loader();
6 
GetVersion()7 DWORD CRKImage::GetVersion()
8 {
9     return m_version;
10 }
GetMergeVersion()11 DWORD CRKImage::GetMergeVersion()
12 {
13     return m_mergeVersion;
14 }
GetReleaseTime()15 STRUCT_RKTIME CRKImage::GetReleaseTime()
16 {
17     return m_releaseTime;
18 }
GetSupportDevice()19 ENUM_RKDEVICE_TYPE CRKImage::GetSupportDevice()
20 {
21     return m_supportDevice;
22 }
GetOsType()23 ENUM_OS_TYPE CRKImage::GetOsType()
24 {
25     UINT *pOsType;
26     pOsType = (UINT *)&m_reserved[4];
27     return (ENUM_OS_TYPE) * pOsType;
28 }
GetBackupSize()29 USHORT CRKImage::GetBackupSize()
30 {
31     USHORT *pBackupSize;
32     pBackupSize = (USHORT *)&m_reserved[12];
33     return *pBackupSize;
34 }
GetBootOffset()35 DWORD CRKImage::GetBootOffset()
36 {
37     return m_bootOffset;
38 }
GetBootSize()39 DWORD CRKImage::GetBootSize()
40 {
41     return m_bootSize;
42 }
GetFWOffset()43 DWORD CRKImage::GetFWOffset()
44 {
45     return m_fwOffset;
46 }
GetFWSize()47 long long CRKImage::GetFWSize()
48 {
49     return m_fwSize;
50 }
51 
GetFWFileHandle()52 FILE *CRKImage::GetFWFileHandle()
53 {
54     return m_pFile;
55 }
56 
GetFwPath()57 char *CRKImage::GetFwPath()
58 {
59     return m_imgPath;
60 }
61 
Md5Check(long long nCheckSize)62 bool CRKImage::Md5Check(long long nCheckSize)
63 {
64     printf("In Md5Check\n");
65     tstring strNewMd5 = _T("");
66     strNewMd5 = CMD5Checksum::GetMD5(m_pFile, nCheckSize);
67     if (strNewMd5.size() == 32)
68     {
69         BYTE newMd5[32];
70         memcpy(newMd5, strNewMd5.c_str(), 32);
71         int i, j;
72         printf("New Md5:\n");
73         for (i = 0; i < 2; i++)
74         {
75             for (j = 0; j < 16; j++)
76             {
77                 printf("%02X ", newMd5[i * 16 + j]);
78             }
79             printf("\r\n");
80         }
81         printf("Old Md5:\n");
82         for (i = 0; i < 2; i++)
83         {
84             for (j = 0; j < 16; j++)
85             {
86                 printf("%02X ", m_md5[i * 16 + j]);
87             }
88             printf("\r\n");
89         }
90         if (memcmp(newMd5, m_md5, 32) != 0)
91         {
92             return false;
93         }
94         else
95         {
96             return true;
97         }
98     }
99     else
100     {
101         return false;
102     }
103 }
104 
SaveBootFile(tstring filename)105 bool CRKImage::SaveBootFile(tstring filename)
106 {
107     FILE *file = NULL;
108     file = fopen(filename.c_str(), _T("wb+"));
109     if (!file)
110     {
111         return false;
112     }
113     BYTE buffer[1024];
114     DWORD dwBufferSize = 1024;
115     DWORD dwBootSize = m_bootSize;
116     DWORD dwReadSize;
117     fseek(m_pFile, m_bootOffset, SEEK_SET);
118     do
119     {
120         dwReadSize = (dwBootSize >= 1024) ? dwBufferSize : dwBootSize;
121         size_t ret = fread(buffer, 1, dwReadSize, m_pFile);
122         if (ret != dwReadSize)
123         {
124             printf("fread error: read:%d, req read:%d", ret, dwReadSize);
125         }
126         fwrite(buffer, 1, dwReadSize, file);
127         dwBootSize -= dwReadSize;
128     } while (dwBootSize > 0);
129     fclose(file);
130     return true;
131 }
132 
SaveFWFile(tstring filename)133 bool CRKImage::SaveFWFile(tstring filename)
134 {
135     FILE *file = NULL;
136     file = fopen(filename.c_str(), _T("wb+"));
137     if (!file)
138     {
139         return false;
140     }
141     BYTE buffer[1024];
142     DWORD dwBufferSize = 1024;
143     long long dwFWSize = m_fwSize;
144     DWORD dwReadSize;
145     fseeko(m_pFile, m_fwOffset, SEEK_SET);
146     do
147     {
148         dwReadSize = (dwFWSize >= 1024) ? dwBufferSize : dwFWSize;
149         size_t ret = fread(buffer, 1, dwReadSize, m_pFile);
150         if (ret != dwReadSize)
151         {
152             printf("fread error: read:%d, req read:%d", ret, dwReadSize);
153         }
154 
155         fwrite(buffer, 1, dwReadSize, file);
156         dwFWSize -= dwReadSize;
157     } while (dwFWSize > 0);
158     fclose(file);
159     return true;
160 }
161 
GetData(long long dwOffset,DWORD dwSize,PBYTE lpBuffer)162 bool CRKImage::GetData(long long dwOffset, DWORD dwSize, PBYTE lpBuffer)
163 {
164     if (dwOffset < 0 || dwSize == 0)
165     {
166         return false;
167     }
168     if (dwOffset + dwSize > m_fileSize)
169     {
170         return false;
171     }
172 
173     fseeko64(m_pFile, dwOffset, SEEK_SET);
174     UINT uiActualRead;
175     uiActualRead = fread(lpBuffer, 1, dwSize, m_pFile);
176     if (dwSize != uiActualRead)
177     {
178         return false;
179     }
180     return true;
181 }
GetReservedData(PBYTE & lpData,USHORT & usSize)182 void CRKImage::GetReservedData(PBYTE &lpData, USHORT &usSize)
183 {
184     lpData = m_reserved;
185     usSize = IMAGE_RESERVED_SIZE;
186 }
GetMd5Data(PBYTE & lpMd5,PBYTE & lpSignMd5)187 int CRKImage::GetMd5Data(PBYTE &lpMd5, PBYTE &lpSignMd5)
188 {
189     lpMd5 = m_md5;
190     lpSignMd5 = m_signMd5;
191     return m_signMd5Size;
192 }
193 
CRKImage(tstring filename,bool & bCheck)194 CRKImage::CRKImage(tstring filename, bool &bCheck)
195 {
196     Version.setContainer(this);
197     Version.getter(&CRKImage::GetVersion);
198     MergeVersion.setContainer(this);
199     MergeVersion.getter(&CRKImage::GetMergeVersion);
200     ReleaseTime.setContainer(this);
201     ReleaseTime.getter(&CRKImage::GetReleaseTime);
202     SupportDevice.setContainer(this);
203     SupportDevice.getter(&CRKImage::GetSupportDevice);
204     OsType.setContainer(this);
205     OsType.getter(&CRKImage::GetOsType);
206     BackupSize.setContainer(this);
207     BackupSize.getter(&CRKImage::GetBackupSize);
208     BootOffset.setContainer(this);
209     BootOffset.getter(&CRKImage::GetBootOffset);
210     BootSize.setContainer(this);
211     BootSize.getter(&CRKImage::GetBootSize);
212     FWOffset.setContainer(this);
213     FWOffset.getter(&CRKImage::GetFWOffset);
214     FWSize.setContainer(this);
215     FWSize.getter(&CRKImage::GetFWSize);
216     FwPath.setContainer(this);
217     FwPath.getter(&CRKImage::GetFwPath);
218 
219     bool bDoMdb5Check = bCheck;
220     struct stat64 statBuf;
221     m_bootObject = NULL;
222     m_pFile = NULL;
223 
224     m_signMd5Size = 0;
225     memset(m_md5, 0, 32);
226     memset(m_signMd5, 0, 256);
227 
228     tchar szName[256];
229     _tcscpy(szName, filename.c_str());
230     if (stat64(szName, &statBuf) < 0)
231     {
232         bCheck = false;
233         printf("CRKImage : stat <%s> happen error.error_reason = %s\n", szName, strerror(errno));
234         return;
235     }
236     if (S_ISDIR(statBuf.st_mode))
237     {
238         bCheck = false;
239         printf("CRKImage : Error! stat mode is DIR\n");
240         return;
241     }
242     m_fileSize = statBuf.st_size;
243     memcpy(m_imgPath, szName, sizeof(szName));
244 
245     bool bOnlyBootFile = false;
246     transform(filename.begin(), filename.end(), filename.begin(), (int(*)(int))tolower);
247     if (filename.find(_T(".bin")) != tstring::npos)
248     {
249         bOnlyBootFile = true;
250     }
251 
252     m_pFile = fopen(szName, "rb");
253     if (!m_pFile)
254     {
255         bCheck = false;
256         printf("CRKImage : fopen <%s> fail,will try use fopen64 \n", szName);
257 
258         m_pFile = fopen64(szName, "rb");
259         if (!m_pFile)
260         {
261             bCheck = false;
262             printf("CRKImage : fopen64 <%s> fail\n", szName);
263             return;
264         }
265     }
266 
267     //code will be error if firmware is signed.md5 is not last 32 byte.
268     //  fseeko(m_pFile,-32,SEEK_END);
269     //  fread(m_md5,1,32,m_pFile);
270     //  fseeko(m_pFile,0,SEEK_SET);
271     //  if (!Md5Check())
272     //  {
273     //      bCheck = false;
274     //      return;
275     //  }
276 
277     int nMd5DataSize;
278     long long ulFwSize;
279     STRUCT_RKIMAGE_HEAD imageHead;
280     if (!bOnlyBootFile)
281     {
282         fseeko64(m_pFile, 0, SEEK_SET);
283         size_t ret = fread((PBYTE)(&imageHead), 1, sizeof(STRUCT_RKIMAGE_HEAD), m_pFile);
284         if (ret != sizeof(STRUCT_RKIMAGE_HEAD))
285         {
286             return;
287         }
288 
289         if (imageHead.uiTag != 0x57464B52)
290         {
291             bCheck = false;
292             printf("CRKImage :Error! imageHead.uiTag != 0x57464B52\n");
293             return;
294         }
295         if ((imageHead.reserved[14] == 'H') && (imageHead.reserved[15] == 'I'))
296         {
297             ulFwSize = *((DWORD *)(&imageHead.reserved[16]));
298             ulFwSize <<= 32;
299             ulFwSize += imageHead.dwFWOffset;
300             ulFwSize += imageHead.dwFWSize;
301         }
302         else
303         {
304             ulFwSize = imageHead.dwFWOffset + imageHead.dwFWSize;
305         }
306         nMd5DataSize = GetImageSize() - ulFwSize;
307         if (nMd5DataSize >= 160)
308         {
309             //sign image
310             m_bSignFlag = true;
311             m_signMd5Size = nMd5DataSize - 32;
312             fseeko64(m_pFile, ulFwSize, SEEK_SET);
313             size_t ret = fread(m_md5, 1, 32, m_pFile);
314             if (ret != 32)
315             {
316                 printf("%s:read error\n", __func__);
317             }
318             ret = fread(m_signMd5, 1, nMd5DataSize - 32, m_pFile);
319             if (ret != nMd5DataSize - 32)
320             {
321                 printf("%s :ret = %d\n", __func__, ret);
322             }
323         }
324         else
325         {
326             fseeko64(m_pFile, -32, SEEK_END);
327             size_t read = fread(m_md5, 1, 32, m_pFile);
328             if (read != 32)
329             {
330                 printf("%s: read error\n", __func__);
331             }
332         }
333         if (bDoMdb5Check)
334         {
335             if (!Md5Check(ulFwSize))
336             {
337                 printf("Md5Check update.img ulFwSize:%ld", ulFwSize);
338                 //bCheck = false;
339                 //return;
340                 bCheck = true;
341             }
342         }
343 
344         m_version = imageHead.dwVersion;
345         m_mergeVersion = imageHead.dwMergeVersion;
346         m_releaseTime.usYear = imageHead.stReleaseTime.usYear;
347         m_releaseTime.ucMonth = imageHead.stReleaseTime.ucMonth;
348         m_releaseTime.ucDay = imageHead.stReleaseTime.ucDay;
349         m_releaseTime.ucHour = imageHead.stReleaseTime.ucHour;
350         m_releaseTime.ucMinute = imageHead.stReleaseTime.ucMinute;
351         m_releaseTime.ucSecond = imageHead.stReleaseTime.ucSecond;
352         m_supportDevice = imageHead.emSupportChip;
353         m_bootOffset = imageHead.dwBootOffset;
354         m_bootSize = imageHead.dwBootSize;
355         m_fwOffset = imageHead.dwFWOffset;
356         m_fwSize = ulFwSize - m_fwOffset;
357 
358         memcpy(m_reserved, imageHead.reserved, IMAGE_RESERVED_SIZE);
359     }
360     else
361     {
362         m_bootOffset = 0;
363         m_bootSize = m_fileSize;
364     }
365 
366     PBYTE lpBoot;
367     lpBoot = new BYTE[m_bootSize];
368     fseeko64(m_pFile, m_bootOffset, SEEK_SET);
369     size_t ret = fread(lpBoot, 1, m_bootSize, m_pFile);
370     if (ret != m_bootSize)
371     {
372         printf("%s : read error\n", __func__);
373     }
374     bool bRet;
375     m_bootObject = new CRKBoot(lpBoot, m_bootSize, bRet);
376     if (!bRet)
377     {
378         bCheck = false;
379         printf("CRKImage :Error! new CRKBoot fail!\n");
380         return;
381     }
382     if (bOnlyBootFile)
383     {
384         m_supportDevice = m_bootObject->SupportDevice;
385         UINT *pOsType;
386         pOsType = (UINT *)&m_reserved[4];
387         *pOsType = (UINT)RK_OS;
388         fclose(m_pFile);
389         m_pFile = NULL;
390     }
391     bCheck = true;
392 }
~CRKImage()393 CRKImage::~CRKImage()
394 {
395     if (m_pFile)
396     {
397         fclose(m_pFile);
398         m_pFile = NULL;
399     }
400     if (m_bootObject)
401     {
402         delete m_bootObject;
403         m_bootObject = NULL;
404     }
405 }
406 
GetImageSize()407 long long CRKImage::GetImageSize()
408 {
409     return m_fileSize;
410 }
411