xref: /OK3568_Linux_fs/external/rkupdate/Upgrade.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 #include <fcntl.h>
2 #include <sys/types.h>
3 #include <sys/stat.h>
4 #include <uuid/uuid.h>
5 
6 #include "RKAndroidDevice.h"
7 
8 #define OTP_NODE_PATH  "/sys/bus/nvmem/devices/rockchip-otp0/nvmem"
9 
10 UpgradeCallbackFunc g_callback = NULL;
11 UpgradeProgressCallbackFunc g_progress_callback = NULL;
12 
13 /* RK3308 loader update*/
IsRK3308_Platform()14 int IsRK3308_Platform()
15 {
16     int fd = -1;
17     int len;
18     char buff[32];
19     fd = open(OTP_NODE_PATH, O_RDONLY);
20     if (fd < 0)
21     {
22         printf("Open OTP node fail!\n");
23         return false;
24     }
25 
26     len = read(fd, buff, sizeof(buff));
27     if (len != sizeof(buff))
28     {
29         printf("read OTP node data fail\n");
30     }
31 
32     close(fd);
33 
34     if (buff[0] == 'R' && buff[1] == 'K' && buff[2] == 0x33 && buff[3] == 0x08)
35     {
36         return 1;
37     }
38     else
39     {
40         int i = 0;
41         for (size_t i = 0; i < 32; i++)
42         {
43             if (i % 16 == 0 && i != 0)
44             {
45                 printf("\n");
46             }
47             printf("%x ", buff[i]);
48         }
49     }
50 
51     return 0;
52 }
53 
Compatible_rk3308bs_loader()54 int Compatible_rk3308bs_loader()
55 {
56     int fd = -1;
57     int len;
58     char buff[32];
59     fd = open(OTP_NODE_PATH, O_RDONLY);
60     if (fd < 0)
61     {
62         printf("Open OTP node fail!\n");
63         return false;
64     }
65 
66     printf("%s: \n", __func__);
67 
68     len = read(fd, buff, sizeof(buff));
69     if (len != sizeof(buff))
70     {
71         printf("read OTP node data fail\n");
72     }
73 
74     close(fd);
75     printf("OTP node data Info: %x \n", buff[28]);
76 
77     return (buff[28] & 0x38) && (buff[28] & 0xc0);
78 }
79 
CreateUid(PBYTE pUid)80 bool CreateUid(PBYTE pUid)
81 {
82     if (!pUid)
83     {
84         return false;
85     }
86     memset(pUid, 0, RKDEVICE_UID_LEN);
87 
88     PBYTE pManufactory, pTime, pGuid, pCrc;
89     pManufactory = pUid;
90     pTime = pManufactory + 8;
91     pGuid = pTime + 4;
92     pCrc = pGuid + 16;
93     memcpy(pManufactory, "ROCKCHIP", 8);
94     time_t now;
95     now = time(NULL);
96     memcpy(pTime, (BYTE *)&now, 4);
97     uuid_t guidValue;
98     uuid_generate(guidValue);
99 
100     memcpy(pGuid, (BYTE *)guidValue, 16);
101 
102     USHORT usCrc = 0;
103     usCrc = CRC_CCITT(pManufactory, 28);
104     memcpy(pCrc, (BYTE *)&usCrc, 2);
105     return true;
106 }
107 
ParsePartitionInfo(string & strPartInfo,string & strName,UINT & uiOffset,UINT & uiLen)108 bool ParsePartitionInfo(string &strPartInfo, string &strName, UINT &uiOffset, UINT &uiLen)
109 {
110     string::size_type pos, prevPos;
111     string strOffset, strLen;
112     int iCount;
113     prevPos = pos = 0;
114     if (strPartInfo.size() <= 0)
115     {
116         return false;
117     }
118     pos = strPartInfo.find('@');
119     if (pos == string::npos)
120     {
121         return false;
122     }
123     strLen = strPartInfo.substr(prevPos, pos - prevPos);
124     strLen.erase(0, strLen.find_first_not_of(_T(" ")));
125     strLen.erase(strLen.find_last_not_of(_T(" ")) + 1);
126     if (strchr(strLen.c_str(), '-'))
127     {
128         uiLen = 0xFFFFFFFF;
129     }
130     else
131     {
132         iCount = sscanf(strLen.c_str(), "0x%x", &uiLen);
133         if (iCount != 1)
134         {
135             return false;
136         }
137     }
138 
139     prevPos = pos + 1;
140     pos = strPartInfo.find('(', prevPos);
141     if (pos == string::npos)
142     {
143         return false;
144     }
145     strOffset = strPartInfo.substr(prevPos, pos - prevPos);
146     strOffset.erase(0, strOffset.find_first_not_of(_T(" ")));
147     strOffset.erase(strOffset.find_last_not_of(_T(" ")) + 1);
148     iCount = sscanf(strOffset.c_str(), "0x%x", &uiOffset);
149     if (iCount != 1)
150     {
151         return false;
152     }
153 
154     prevPos = pos + 1;
155     pos = strPartInfo.find(')', prevPos);
156     if (pos == string::npos)
157     {
158         return false;
159     }
160     strName = strPartInfo.substr(prevPos, pos - prevPos);
161     strName.erase(0, strName.find_first_not_of(_T(" ")));
162     strName.erase(strName.find_last_not_of(_T(" ")) + 1);
163 
164     return true;
165 }
166 
parse_parameter(char * pParameter,PARAM_ITEM_VECTOR & vecItem)167 bool parse_parameter(char *pParameter, PARAM_ITEM_VECTOR &vecItem)
168 {
169     stringstream paramStream(pParameter);
170     bool bRet, bFind = false;
171     string strLine, strPartition, strPartInfo, strPartName;
172     string::size_type line_size, pos, posColon, posComma;
173     UINT uiPartOffset, uiPartSize;
174     STRUCT_PARAM_ITEM item;
175     vecItem.clear();
176     while (!paramStream.eof())
177     {
178         getline(paramStream, strLine);
179         line_size = strLine.size();
180         if (line_size == 0)
181         {
182             continue;
183         }
184         if (strLine[0] == '#')
185         {
186             continue;
187         }
188         if (strLine[line_size - 1] == '\r')
189         {
190             strLine = strLine.substr(0, line_size - 1);
191         }
192         pos = strLine.find("mtdparts");
193         if (pos == string::npos)
194         {
195             continue;
196         }
197         bFind = true;
198         posColon = strLine.find(':', pos);
199         if (posColon == string::npos)
200         {
201             continue;
202         }
203         strPartition = strLine.substr(posColon + 1);
204         //��ȡ������Ϣ
205         pos = 0;
206         posComma = strPartition.find(',', pos);
207         while (posComma != string::npos)
208         {
209             strPartInfo = strPartition.substr(pos, posComma - pos);
210             bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize);
211             if (bRet)
212             {
213                 strcpy(item.szItemName, strPartName.c_str());
214                 item.uiItemOffset = uiPartOffset;
215                 item.uiItemSize = uiPartSize;
216                 vecItem.push_back(item);
217             }
218             pos = posComma + 1;
219             posComma = strPartition.find(',', pos);
220         }
221         strPartInfo = strPartition.substr(pos);
222         if (strPartInfo.size() > 0)
223         {
224             bRet = ParsePartitionInfo(strPartInfo, strPartName, uiPartOffset, uiPartSize);
225             if (bRet)
226             {
227                 strcpy(item.szItemName, strPartName.c_str());
228                 item.uiItemOffset = uiPartOffset;
229                 item.uiItemSize = uiPartSize;
230                 vecItem.push_back(item);
231             }
232         }
233         break;
234     }
235     return bFind;
236 }
237 
get_parameter_loader(CRKComm * pComm,char * pParameter,int & nParamSize)238 bool get_parameter_loader(CRKComm *pComm, char *pParameter, int &nParamSize)
239 {
240     if ((nParamSize != -1) && (!pParameter))
241     {
242         return false;
243     }
244     BYTE paramHead[512];
245     DWORD *pParamTag = (DWORD *)paramHead;
246     DWORD *pParamSize = (DWORD *)(paramHead + 4);
247     int iRet;
248 
249     iRet = pComm->RKU_ReadLBA(0, 1, paramHead);
250     if (iRet != ERR_SUCCESS)
251     {
252         return false;
253     }
254     if (*pParamTag != 0x4D524150)
255     {
256         return false;
257     }
258     if (nParamSize == -1)
259     {
260         //��ȡparameter��С
261         nParamSize = *pParamSize;
262         return true;
263     }
264     if (nParamSize < *pParamSize)
265     {
266         return false;
267     }
268 
269     nParamSize = *pParamSize;
270     int nParamSec;
271     nParamSec = (nParamSize + 12 - 1) / 512 + 1;
272     PBYTE pBuffer = NULL;
273     pBuffer = new BYTE[nParamSec * 512];
274     if (!pBuffer)
275     {
276         return false;
277     }
278     iRet = pComm->RKU_ReadLBA(0, nParamSec, pBuffer);
279     if (iRet != ERR_SUCCESS)
280     {
281         delete []pBuffer;
282         pBuffer = NULL;
283         return false;
284     }
285 
286     memcpy(pParameter, pBuffer + 8, nParamSize);
287     delete []pBuffer;
288     pBuffer = NULL;
289     return true;
290 }
291 
read_bytes_from_partition(DWORD dwPartitionOffset,long long ullstart,DWORD dwCount,PBYTE pOut,CRKComm * pComm)292 bool read_bytes_from_partition(DWORD dwPartitionOffset, long long ullstart, DWORD dwCount, PBYTE pOut, CRKComm *pComm)
293 {
294     int iRet;
295     UINT uiTransferSize = 16 * 1024;
296     UINT uiTransferSec = uiTransferSize / SECTOR_SIZE;
297     BYTE *pBuffer = NULL;
298     UINT uiBegin = dwPartitionOffset, uiLen, uiReadBytes = 0, uiTmp;
299     DWORD dwWritePos = 0;
300     pBuffer = new BYTE[uiTransferSize];
301     if (!pBuffer)
302     {
303         return false;
304     }
305     uiTmp = ullstart % 2048;
306     if (uiTmp == 0)
307     {
308         uiBegin += ullstart / SECTOR_SIZE;
309     }
310     else
311     {
312         uiReadBytes = 2048 - uiTmp;
313         uiBegin += ((ullstart / 2048) * 4);
314         uiLen = 4;
315         iRet = pComm->RKU_ReadLBA(uiBegin, uiLen, pBuffer);
316         if (iRet != ERR_SUCCESS)
317         {
318             delete []pBuffer;
319             return false;
320         }
321         if (dwCount >= uiReadBytes)
322         {
323             memcpy(pOut + dwWritePos, pBuffer + uiTmp, uiReadBytes);
324             dwWritePos += uiReadBytes;
325             dwCount -= uiReadBytes;
326         }
327         else
328         {
329             memcpy(pOut + dwWritePos, pBuffer + uiTmp, dwCount);
330             dwWritePos += dwCount;
331             dwCount = 0;
332         }
333         uiBegin += uiLen;
334     }
335     while (dwCount > 0)
336     {
337         if (dwCount >= uiTransferSize)
338         {
339             uiReadBytes = uiTransferSize;
340             uiLen = uiTransferSec;
341         }
342         else
343         {
344             uiReadBytes = dwCount;
345             uiLen = BYTE2SECTOR(uiReadBytes);
346         }
347         iRet = pComm->RKU_ReadLBA(uiBegin, uiLen, pBuffer);
348         if (iRet != ERR_SUCCESS)
349         {
350             delete []pBuffer;
351             return false;
352         }
353         memcpy(pOut + dwWritePos, pBuffer, uiReadBytes);
354         dwWritePos += uiReadBytes;
355         dwCount -= uiReadBytes;
356         uiBegin += uiLen;
357     }
358     delete []pBuffer;
359     return true;
360 }
361 
check_fw_header(CRKComm * pComm,DWORD dwOffset,PSTRUCT_RKIMAGE_HDR pHeader,CRKLog * pLog=NULL)362 bool check_fw_header(CRKComm *pComm, DWORD dwOffset, PSTRUCT_RKIMAGE_HDR pHeader, CRKLog *pLog = NULL)
363 {
364     int nHeaderSec = BYTE2SECTOR(sizeof(STRUCT_RKIMAGE_HDR));
365     char model[256] = {0};
366     PBYTE pBuf = NULL;
367     pBuf = new BYTE[nHeaderSec * SECTOR_SIZE];
368     if (!pBuf)
369     {
370         return false;
371     }
372     int iRet;
373     iRet = pComm->RKU_ReadLBA(dwOffset, nHeaderSec, pBuf);
374     if (iRet != ERR_SUCCESS)
375     {
376         delete []pBuf;
377         pBuf = NULL;
378         return false;
379     }
380     memcpy(pHeader, pBuf, sizeof(STRUCT_RKIMAGE_HDR));
381     delete []pBuf;
382     pBuf = NULL;
383     if (pHeader->tag != RKIMAGE_TAG)
384     {
385         return false;
386     }
387 
388     #if 0 //chad.ma close
389     property_get("ro.product.model", model, "");
390     if (pLog)
391     {
392         pLog->Record(_T("model:%s\nbackup firmware model:%s\n"), model, pHeader->machine_model);
393     }
394     if (strcmp(model, pHeader->machine_model))
395     {
396         return false;
397     }
398     #endif
399 
400     return true;
401 }
check_fw_crc(CRKComm * pComm,DWORD dwOffset,PSTRUCT_RKIMAGE_HDR pHeader,CRKLog * pLog=NULL)402 bool check_fw_crc(CRKComm *pComm, DWORD dwOffset, PSTRUCT_RKIMAGE_HDR pHeader, CRKLog *pLog = NULL)
403 {
404     int iRet;
405     long long ullRemain, ullCrcOffset;
406     if (pHeader->machine_model[29] == 'H')
407     {
408         ullRemain = *((DWORD *)(&pHeader->machine_model[30]));
409         ullRemain <<= 32;
410         ullRemain += pHeader->size;
411     }
412     else
413     {
414         ullRemain = pHeader->size;
415     }
416     if (ullRemain <= 0)
417     {
418         return false;
419     }
420     ullCrcOffset = ullRemain;
421     UINT uiTransferSize = 16 * 1024;
422     UINT uiTransferSec = uiTransferSize / SECTOR_SIZE;
423     BYTE *pBuffer = NULL;
424     BYTE oldCrc[4];
425     UINT uiBegin = dwOffset, uiLen, uiCrc = 0, uiReadBytes = 0;
426     pBuffer = new BYTE[uiTransferSize];
427     if (!pBuffer)
428     {
429         return false;
430     }
431     while (ullRemain > 0)
432     {
433         if (ullRemain >= uiTransferSize)
434         {
435             uiReadBytes = uiTransferSize;
436             uiLen = uiTransferSec;
437         }
438         else
439         {
440             uiReadBytes = ullRemain;
441             uiLen = BYTE2SECTOR(uiReadBytes);
442         }
443         iRet = pComm->RKU_ReadLBA(uiBegin, uiLen, pBuffer);
444         if (iRet != ERR_SUCCESS)
445         {
446             delete []pBuffer;
447             if (pLog)
448             {
449                 pLog->Record(_T("ERROR:check_fw_crc-->RKU_ReadLBA failed,err=%d"), iRet);
450             }
451             return false;
452         }
453         uiCrc = CRC_32(pBuffer, uiReadBytes, uiCrc);
454         uiBegin += uiLen;
455         ullRemain -= uiReadBytes;
456     }
457     delete []pBuffer;
458     if (!read_bytes_from_partition(dwOffset, ullCrcOffset, 4, oldCrc, pComm))
459     {
460         if (pLog)
461         {
462             pLog->Record(_T("ERROR:check_fw_crc-->read old crc failed"));
463         }
464         return false;
465     }
466     if (uiCrc != *((UINT *)(oldCrc)))
467     {
468         return false;
469     }
470     return true;
471 }
472 
download_backup_image(PARAM_ITEM_VECTOR & vecParam,char * pszItemName,DWORD dwBackupOffset,STRUCT_RKIMAGE_HDR & hdr,CRKComm * pComm,CRKLog * pLog=NULL)473 bool download_backup_image(PARAM_ITEM_VECTOR &vecParam, char *pszItemName, DWORD dwBackupOffset, STRUCT_RKIMAGE_HDR &hdr,
474                            CRKComm *pComm, CRKLog *pLog = NULL)
475 {
476     DWORD dwToOffset, dwToSize;
477     int i, iRet;
478     if (g_progress_callback)
479     {
480         g_progress_callback(0.5, 50);
481     }
482     for (i = 0; i < vecParam.size(); i++)
483     {
484         if (strcmp(pszItemName, vecParam[i].szItemName) == 0)
485         {
486             dwToOffset = vecParam[i].uiItemOffset;
487             dwToSize = vecParam[i].uiItemSize;
488             break;
489         }
490     }
491     if (i >= vecParam.size())
492     {
493         if (pLog)
494         {
495             pLog->Record(_T("ERROR:download_backup_image-->no found dest partition."));
496         }
497         return false;
498     }
499     long long ullSrcPos, ullSrcSize;
500     for (i = 0; i < hdr.item_count; i++)
501     {
502         if (strcmp(pszItemName, hdr.item[i].name) == 0)
503         {
504             if (hdr.item[i].file[50] == 'H')
505             {
506                 ullSrcPos = *((DWORD *)(&hdr.item[i].file[51]));
507                 ullSrcPos <<= 32;
508                 ullSrcPos += hdr.item[i].offset;
509             }
510             else
511             {
512                 ullSrcPos = hdr.item[i].offset;
513             }
514             if (hdr.item[i].file[55] == 'H')
515             {
516                 ullSrcSize = *((DWORD *)(&hdr.item[i].file[56]));
517                 ullSrcSize <<= 32;
518                 ullSrcSize += hdr.item[i].size;
519             }
520             else
521             {
522                 ullSrcSize = hdr.item[i].size;
523             }
524             break;
525         }
526     }
527     if (i >= hdr.item_count)
528     {
529         if (pLog)
530         {
531             pLog->Record(_T("ERROR:download_backup_image-->no found source in the backup."));
532         }
533         return false;
534     }
535     long long ullRemain, ullstart, ullToStart;
536     UINT uiBegin, uiLen, uiTransferByte;
537     UINT uiBufferSize = 16 * 1024;
538     BYTE buffer[16 * 1024];
539     BYTE readbuffer[16 * 1024];
540 
541     //write image
542     ullRemain = ullSrcSize;
543     uiBegin = dwToOffset;
544     ullstart = ullSrcPos;
545     while (ullRemain > 0)
546     {
547         if (ullRemain >= uiBufferSize)
548         {
549             uiTransferByte = uiBufferSize;
550             uiLen = 32;
551         }
552         else
553         {
554             uiTransferByte = ullRemain;
555             uiLen = BYTE2SECTOR(uiTransferByte);
556         }
557         if (!read_bytes_from_partition(dwBackupOffset, ullstart, uiTransferByte, buffer, pComm))
558         {
559             if (pLog)
560             {
561                 pLog->Record(_T("ERROR:download_backup_image-->read data from backup failed."));
562             }
563             return false;
564         }
565         iRet = pComm->RKU_WriteLBA(uiBegin, uiLen, buffer);
566         if (iRet != ERR_SUCCESS)
567         {
568             if (pLog)
569             {
570                 pLog->Record(_T("ERROR:download_backup_image-->write data to partition failed."));
571             }
572             return false;
573         }
574         ullRemain -= uiTransferByte;
575         uiBegin += uiLen;
576         ullstart += uiTransferByte;
577 
578     }
579     pComm->RKU_ReopenLBAHandle();
580     if (g_progress_callback)
581     {
582         g_progress_callback(1, 0);
583     }
584     if (g_progress_callback)
585     {
586         g_progress_callback(0.4, 30);
587     }
588     //check image
589     if (pLog)
590     {
591         pLog->Record(_T("Start to check system..."));
592     }
593     ullRemain = ullSrcSize;
594     ullToStart = 0;
595     ullstart = ullSrcPos;
596     while (ullRemain > 0)
597     {
598         if (ullRemain >= uiBufferSize)
599         {
600             uiTransferByte = uiBufferSize;
601         }
602         else
603         {
604             uiTransferByte = ullRemain;
605         }
606         if (!read_bytes_from_partition(dwBackupOffset, ullstart, uiTransferByte, buffer, pComm))
607         {
608             if (pLog)
609             {
610                 pLog->Record(_T("ERROR:download_backup_image-->read data from backup failed."));
611             }
612             return false;
613         }
614         if (!read_bytes_from_partition(dwToOffset, ullToStart, uiTransferByte, readbuffer, pComm))
615         {
616             if (pLog)
617             {
618                 pLog->Record(_T("ERROR:download_backup_image-->read data from partition failed."));
619             }
620             return false;
621         }
622         if (memcmp(buffer, readbuffer, uiTransferByte) != 0)
623         {
624             if (pLog)
625             {
626                 pLog->Record(_T("ERROR:download_backup_image-->compare data failed."));
627             }
628             return false;
629         }
630 
631         ullRemain -= uiTransferByte;
632         ullToStart += uiTransferByte;
633         ullstart += uiTransferByte;
634 
635     }
636     if (g_progress_callback)
637     {
638         g_progress_callback(1, 0);
639     }
640     return true;
641 }
642 
IsDeviceLock(CRKComm * pComm,bool & bLock)643 bool IsDeviceLock(CRKComm *pComm, bool &bLock)
644 {
645     int iRet;
646     BYTE buffer[4];
647     iRet = pComm->RKU_GetLockFlag(buffer);
648     if (iRet != ERR_SUCCESS)
649     {
650         return false;
651     }
652     DWORD *pFlag = (DWORD *)buffer;
653     if (*pFlag == 1)
654     {
655         bLock = true;
656     }
657     else
658     {
659         bLock = false;
660     }
661     return true;
662 }
663 
GetPubicKeyFromExternal(char * szDev,CRKLog * pLog,unsigned char * pKey,unsigned int & nKeySize)664 bool GetPubicKeyFromExternal(char *szDev, CRKLog *pLog, unsigned char *pKey, unsigned int &nKeySize)
665 {
666     int hDev = -1;
667     int j, ret, nRsaByte;
668     bool bSuccess = false;
669     BYTE bData[SECTOR_SIZE * 8];
670     PRKANDROID_IDB_SEC0 pSec0 = (PRKANDROID_IDB_SEC0)bData;
671     PRK_SECURE_HEADER pSecureHdr = (PRK_SECURE_HEADER)(bData + SECTOR_SIZE * 4);
672     string strOutput;
673     if (!szDev)
674     {
675         printf("In GetPubicKeyFromExternal device=NULL\n");
676         return false;
677     }
678     else
679     {
680         printf("In GetPubicKeyFromExternal device=%s\n", szDev);
681     }
682     hDev = open(szDev, O_RDONLY, 0);
683     if (hDev < 0)
684     {
685         if (pLog)
686         {
687             pLog->Record(_T("ERROR:GetPubicKeyFromExternal-->open %s failed,err=%d"), szDev, errno);
688         }
689         goto Exit_GetPubicKeyFromExternal;
690     }
691     else
692     {
693         if (pLog)
694         {
695             pLog->Record(_T("INFO:GetPubicKeyFromExternal-->%s=%d"), szDev, hDev);
696         }
697     }
698 
699     ret = lseek(hDev, 64 * 512, SEEK_SET);
700     if (ret < 0)
701     {
702         if (pLog)
703         {
704             pLog->Record(_T("ERROR:GetPubicKeyFromExternal-->seek IDBlock failed,err=%d"), errno);
705         }
706         goto Exit_GetPubicKeyFromExternal;
707     }
708     ret = read(hDev, bData, 8 * 512);
709     if (ret != 8 * 512)
710     {
711         if (pLog)
712         {
713             pLog->Record(_T("ERROR:GetPubicKeyFromExternal-->read IDBlock failed,err=%d"), errno);
714         }
715         goto Exit_GetPubicKeyFromExternal;
716     }
717     //  if (pLog)
718     //  {
719     //      pLog->PrintBuffer(strOutput,bData,512,16);
720     //      pLog->Record("INFO:idb\n%s",strOutput.c_str());
721     //  }
722     P_RC4(bData, SECTOR_SIZE);
723     //  if (pLog)
724     //  {
725     //      pLog->PrintBuffer(strOutput,bData,512,16);
726     //      pLog->Record("INFO:idb rc4\n%s",strOutput.c_str());
727     //  }
728     if (pSec0->dwTag != 0x0FF0AA55)
729     {
730         if (pLog)
731         {
732             pLog->Record(_T("ERROR:GetPubicKeyFromExternal-->check IDBlock failed,tag=0x%x"), pSec0->dwTag);
733         }
734         goto Exit_GetPubicKeyFromExternal;
735     }
736     if (pSec0->uiRc4Flag == 0)
737     {
738         for (j = 0; j < 4; j++)
739         {
740             P_RC4(bData + SECTOR_SIZE * (j + 4), SECTOR_SIZE);
741         }
742     }
743     if (pSecureHdr->uiTag != 0x4B415352)
744     {
745         if (pLog)
746         {
747             pLog->Record(_T("ERROR:GetPubicKeyFromExternal-->check SecureHeader failed,tag=0x%x"), pSecureHdr->uiTag);
748         }
749         goto Exit_GetPubicKeyFromExternal;
750     }
751     nRsaByte = pSecureHdr->usRsaBit / 8;
752     *((USHORT *)pKey) = pSecureHdr->usRsaBit;
753     for (j = 0; j < nRsaByte; j++)
754     {
755         *(pKey + j + 2) = pSecureHdr->nFactor[nRsaByte - j - 1];
756     }
757     for (j = 0; j < nRsaByte; j++)
758     {
759         *(pKey + j + 2 + nRsaByte) = pSecureHdr->eFactor[nRsaByte - j - 1];
760     }
761     nKeySize = nRsaByte * 2 + 2;
762     //  if (pLog)
763     //  {
764     //      pLog->PrintBuffer(strOutput,pKey,nKeySize,16);
765     //      pLog->Record("INFO:Key\n%s",strOutput.c_str());
766     //  }
767     bSuccess = true;
768 Exit_GetPubicKeyFromExternal:
769     if (hDev != -1)
770     {
771         close(hDev);
772     }
773     return bSuccess;
774 }
775 
GetPubicKeyFromDevice(CRKLog * pLog,unsigned char * pKey,unsigned int & nKeySize)776 bool GetPubicKeyFromDevice(CRKLog *pLog, unsigned char *pKey, unsigned int &nKeySize)
777 {
778     bool bSuccess = false, bRet;
779     CRKComm *pComm = NULL;
780     CRKAndroidDevice *pDevice = NULL;
781     STRUCT_RKDEVICE_DESC device;
782     pComm = new CRKUsbComm(pLog);
783     if (!pComm)
784     {
785         pLog->Record("ERROR:GetPubicKeyFromDevice-->new CRKComm failed!");
786         goto EXIT_GetPubicKeyFromDevice;
787     }
788     pDevice = new CRKAndroidDevice(device);
789     if (!pDevice)
790     {
791         pLog->Record("ERROR:GetPubicKeyFromDevice-->new CRKAndroidDevice failed!");
792         goto EXIT_GetPubicKeyFromDevice;
793     }
794     pDevice->SetObject(NULL, pComm, pLog);
795     pDevice->m_pCallback = (UpgradeCallbackFunc)NULL;
796     pDevice->m_pProcessCallback = (UpgradeProgressCallbackFunc)NULL;
797     bRet = pDevice->GetPublicKey(pKey, nKeySize);
798     if (!bRet)
799     {
800         pLog->Record("ERROR:GetPubicKeyFromDevice-->GetPublicKey failed!");
801         goto EXIT_GetPubicKeyFromDevice;
802     }
803     bSuccess = true;
804 EXIT_GetPubicKeyFromDevice:
805     if (pDevice)
806     {
807         delete pDevice;
808         pDevice = NULL;
809     }
810     else if (pComm)
811     {
812         delete pComm;
813         pComm = NULL;
814     }
815     return bSuccess;
816 }
817 
UnlockDevice(CRKImage * pImage,CRKLog * pLog,unsigned char * pKey,unsigned int nKeySize)818 bool UnlockDevice(CRKImage *pImage, CRKLog *pLog, unsigned char *pKey, unsigned int nKeySize)
819 {
820     PBYTE pMd5, pSignMd5;
821     int nSignSize;
822     unsigned int nOutput;
823     bool bRet;
824     BYTE output[256];
825     string strOutput;
826     printf("in UnlockDevice\n");
827     if ((!pImage) || (!pKey))
828     {
829         return false;
830     }
831     nSignSize = pImage->GetMd5Data(pMd5, pSignMd5);
832     if (nSignSize == 0)
833     {
834         if (pLog)
835         {
836             pLog->Record("Get signed info failed.");
837         }
838         return false;
839     }
840     //bRet= DoRsa(output,&nOutput,pSignMd5,nSignSize,pKey,nKeySize);
841     //if (!bRet)
842     //{
843     //  if (pLog)
844     //      pLog->Record("DoRsa failed.");
845     //  return false;
846     //}
847     if (pLog)
848     {
849         pLog->PrintBuffer(strOutput, pMd5, 32, 16);
850         pLog->Record("INFO:Old Md5\n%s", strOutput.c_str());
851         pLog->PrintBuffer(strOutput, output + nOutput - 32, 32, 16);
852         pLog->Record("INFO:New Md5\n%s", strOutput.c_str());
853     }
854     return true;
855     if (memcmp(pMd5, output + nOutput - 32, 32) == 0)
856     {
857         return true;
858     }
859     else
860     {
861         return false;
862     }
863 }
864 
865 extern int sdBootUpdate;
do_rk_firmware_upgrade(char * szFw,void * pCallback,void * pProgressCallback,char * szBootDev)866 bool do_rk_firmware_upgrade(char *szFw, void *pCallback, void *pProgressCallback, char *szBootDev)
867 {
868     bool bSuccess = false, bRet = false, bLock;
869     int iRet;
870     CRKImage *pImage = NULL;
871     CRKLog *pLog = NULL;
872     CRKAndroidDevice *pDevice = NULL;
873     CRKComm *pComm = NULL;
874     STRUCT_RKDEVICE_DESC device;
875     BYTE key[514];
876     UINT nKeySize = 514;
877     BYTE uid[RKDEVICE_UID_LEN];
878     tstring strFw = szFw;
879     tstring strUid;
880     bool bUpdateLoader = true;
881 
882     g_callback = (UpgradeCallbackFunc)pCallback;
883     g_progress_callback = (UpgradeProgressCallbackFunc)pProgressCallback;
884     if (g_progress_callback)
885     {
886         g_progress_callback(0.1, 10);
887     }
888 
889     pLog = new CRKLog();
890     if (!pLog)
891     {
892         goto EXIT_UPGRADE;
893     }
894     pLog->Record("Start to upgrade firmware...");
895     pImage = new CRKImage(strFw, bRet);
896     if (!bRet)
897     {
898         pLog->Record("ERROR:do_rk_firmware_upgrade-->new CRKImage failed!");
899         goto EXIT_UPGRADE;
900     }
901     pComm = new CRKUsbComm(pLog);
902     if (!pComm)
903     {
904         pLog->Record("ERROR:do_rk_firmware_upgrade-->new CRKComm failed!");
905         goto EXIT_UPGRADE;
906     }
907 
908     pDevice = new CRKAndroidDevice(device);
909     if (!pDevice)
910     {
911         pLog->Record("ERROR:do_rk_firmware_upgrade-->new CRKAndroidDevice failed!");
912         goto EXIT_UPGRADE;
913     }
914     pDevice->SetObject(pImage, pComm, pLog);
915 
916     if (!pComm->RKU_IsEmmcFlash())    //chad.ma if is Emmc flash don't create UUID.
917     {
918         if (CreateUid(uid))
919         {
920             pDevice->Uid = uid;
921             pLog->PrintBuffer(strUid, uid, RKDEVICE_UID_LEN);
922             pLog->Record("uid:%s", strUid.c_str());
923         }
924     }
925 
926     pDevice->m_pCallback = (UpgradeCallbackFunc)pCallback;
927     pDevice->m_pProcessCallback = (UpgradeProgressCallbackFunc)pProgressCallback;
928     pLog->Record("Get FlashInfo...");
929     bRet = pDevice->GetFlashInfo();
930     if (!bRet)
931     {
932         pLog->Record("ERROR:do_rk_firmware_upgrade-->GetFlashInfo failed!");
933         goto EXIT_UPGRADE;
934     }
935 
936     bUpdateLoader = pDevice->IsExistBootloaderInFw();
937 
938     if (IsRK3308_Platform() && Compatible_rk3308bs_loader())
939     {
940         bool bFound_3308bs_loader = false;
941         const char *rk3308bs_loader = "rk3308bs_loader";
942         DWORD rk3308bs_loaderOffset = 0;
943         DWORD rk3308bs_loaderSize   = 0;
944 
945         bUpdateLoader = false;
946         if (pDevice->IsExistPartitionInFw(rk3308bs_loader, rk3308bs_loaderOffset, rk3308bs_loaderSize))
947         {
948             printf("Found RK3308bs loader in fw and offset :%d size :%d.\n",
949                    rk3308bs_loaderOffset, rk3308bs_loaderSize);
950 
951             if (pImage->m_bootObject)
952             {
953                 delete pImage->m_bootObject;
954 
955                 bool bRet;
956                 PBYTE lpBoot;
957                 lpBoot = new BYTE[rk3308bs_loaderSize];
958 
959                 long offset = rk3308bs_loaderOffset + pImage->GetFWOffset();
960                 fseeko64(pImage->GetFWFileHandle(), offset, SEEK_SET);
961                 size_t ret = fread(lpBoot, 1, rk3308bs_loaderSize, pImage->GetFWFileHandle());
962                 if (ret != rk3308bs_loaderSize)
963                 {
964                     printf("%s : read error\n", __func__);
965                 }
966                 pImage->m_bootObject = new CRKBoot(lpBoot, rk3308bs_loaderSize, bRet);
967                 if (!bRet)
968                 {
969                     printf("CRKImage :Error! new CRKBoot fail!\n");
970                     return false;
971                 }
972                 bUpdateLoader = true;
973             }
974         }
975     }
976 
977     #ifndef USE_SIGNATURE_FW
978     if (bUpdateLoader)
979     {
980         printf("############### update bootloader start ############\n");
981 
982         pLog->Record("IDBlock Preparing...");
983         printf("\t\t############### IDBlock Preparing...\n");
984         iRet = pDevice->PrepareIDB();
985         if (iRet != ERR_SUCCESS)
986         {
987             pLog->Record("ERROR:do_rk_firmware_upgrade-->PrepareIDB failed!");
988             goto EXIT_UPGRADE;
989         }
990         pLog->Record("IDBlock Writing...");
991         printf("\t\t############### IDBlock Writing...\n");
992         iRet = pDevice->DownloadIDBlock();
993         if (iRet != ERR_SUCCESS)
994         {
995             pLog->Record("ERROR:do_rk_firmware_upgrade-->DownloadIDBlock failed!");
996             goto EXIT_UPGRADE;
997         }
998         printf("############### update bootloader Success############\n");
999 
1000         if (strFw.find(_T(".bin")) != tstring::npos)
1001         {
1002             pLog->Record("INFO:do_rk_firmware_upgrade-->Download loader only success!");
1003             bSuccess = true;
1004             return bSuccess;
1005         }
1006     }
1007 
1008     iRet = pDevice->DownloadImage();
1009     if (iRet != ERR_SUCCESS)
1010     {
1011         pLog->Record("ERROR:do_rk_firmware_upgrade-->DownloadImage failed!");
1012         goto EXIT_UPGRADE;
1013     }
1014 
1015     #else
1016     printf("use signature firmware to update.\n");
1017     iRet = pDevice->DownloadImage();
1018     if (iRet != ERR_SUCCESS)
1019     {
1020         pLog->Record("ERROR:do_rk_firmware_upgrade-->DownloadImage failed!");
1021         goto EXIT_UPGRADE;
1022     }
1023 
1024     if (bUpdateLoader)
1025     {
1026         printf("############### update bootloader start ############\n");
1027         pLog->Record("IDBlock Preparing...");
1028         printf("\t\t ############### IDBlock Preparing...\n");
1029         iRet = pDevice->PrepareIDB();
1030         if (iRet != ERR_SUCCESS)
1031         {
1032             pLog->Record("ERROR:do_rk_firmware_upgrade-->PrepareIDB failed!");
1033             goto EXIT_UPGRADE;
1034         }
1035         pLog->Record("IDBlock Writing...");
1036         printf("\t\t ############### IDBlock Writing...\n");
1037         iRet = pDevice->DownloadIDBlock();
1038         if (iRet != ERR_SUCCESS)
1039         {
1040             pLog->Record("ERROR:do_rk_firmware_upgrade-->DownloadIDBlock failed!");
1041             goto EXIT_UPGRADE;
1042         }
1043         printf("############### update bootloader Success############\n");
1044 
1045         if (strFw.find(_T(".bin")) != tstring::npos)
1046         {
1047             pLog->Record("INFO:do_rk_firmware_upgrade-->Download loader only success!");
1048             bSuccess = true;
1049             return bSuccess;
1050         }
1051     }
1052     #endif
1053 
1054     bSuccess = true;
1055 
1056 EXIT_UPGRADE:
1057     if (bSuccess)
1058     {
1059         pLog->Record("Finish to upgrade firmware.");
1060     }
1061     else
1062     {
1063         pLog->Record("Fail to upgrade firmware!");
1064     }
1065     if (pLog)
1066     {
1067         delete pLog;
1068         pLog = NULL;
1069     }
1070     if (pImage)
1071     {
1072         delete pImage;
1073         pImage = NULL;
1074     }
1075     if (pDevice)
1076     {
1077         delete pDevice;
1078         pDevice = NULL;
1079     }
1080     else
1081     {
1082         if (pComm)
1083         {
1084             delete pComm;
1085             pComm = NULL;
1086         }
1087     }
1088 
1089     return bSuccess;
1090 }
1091 
do_rk_partition_upgrade(char * szFw,void * pCallback,void * pProgressCallback,char nBoot,char * szBootDev)1092 bool do_rk_partition_upgrade(char *szFw, void *pCallback, void *pProgressCallback, char nBoot, char *szBootDev)
1093 {
1094     bool bSuccess = false, bRet = false, bLock;
1095     int iRet;
1096     CRKImage *pImage = NULL;
1097     CRKLog *pLog = NULL;
1098     CRKAndroidDevice *pDevice = NULL;
1099     CRKComm *pComm = NULL;
1100     STRUCT_RKDEVICE_DESC device;
1101     BYTE key[514];
1102     UINT nKeySize = 514;
1103     tstring strFw = szFw;
1104     vector<int> vecDownloadEntry;
1105     vecDownloadEntry.clear();
1106     g_callback = (UpgradeCallbackFunc)pCallback;
1107     g_progress_callback = (UpgradeProgressCallbackFunc)pProgressCallback;
1108     if (g_progress_callback)
1109     {
1110         g_progress_callback(0.1, 5);
1111     }
1112     pLog = new CRKLog();
1113     if (!pLog)
1114     {
1115         goto EXIT_DOWNLOAD;
1116     }
1117     pLog->Record("Start to upgrade partition...");
1118 
1119     pComm = new CRKUsbComm(pLog);
1120     if (!pComm)
1121     {
1122         pLog->Record("ERROR:do_rk_partition_upgrade-->new CRKComm failed!");
1123         goto EXIT_DOWNLOAD;
1124     }
1125     if (IsDeviceLock(pComm, bLock))
1126     {
1127         if (bLock)
1128         {
1129             bRet = true;
1130             pImage = new CRKImage(strFw, bRet);
1131             if (!bRet)
1132             {
1133                 pLog->Record("ERROR:do_rk_partition_upgrade-->new CRKImage with check failed,%s!", szFw);
1134                 goto EXIT_DOWNLOAD;
1135             }
1136             if (nBoot == 0) //get key from nand or emmc
1137             {
1138                 bRet = GetPubicKeyFromDevice(pLog, key, nKeySize);
1139             }
1140             else if ((nBoot == 1) || (nBoot == 2)) //get key from sd or usb disk
1141             {
1142                 bRet = GetPubicKeyFromExternal(szBootDev, pLog, key, nKeySize);
1143             }
1144             else
1145             {
1146                 bRet = false;
1147             }
1148             if (!bRet)
1149             {
1150                 if (szBootDev)
1151                 {
1152                     pLog->Record("ERROR:do_rk_partition_upgrade-->Get PubicKey failed,boot=%d,dev=%s!", nBoot, szBootDev);
1153                 }
1154                 else
1155                 {
1156                     pLog->Record("ERROR:do_rk_partition_upgrade-->Get PubicKey failed,boot=%d,dev=NULL!", nBoot);
1157                 }
1158                 goto EXIT_DOWNLOAD;
1159             }
1160 
1161             if (!UnlockDevice(pImage, pLog, key, nKeySize))
1162             {
1163                 pLog->Record("ERROR:do_rk_partition_upgrade-->UnlockDevice failed!");
1164                 goto EXIT_DOWNLOAD;
1165             }
1166             //          if (pCallback)
1167             //              ((UpgradeCallbackFunc)pCallback)("pause");
1168         }
1169         else
1170         {
1171             pImage = new CRKImage(strFw, bRet);
1172             if (!bRet)
1173             {
1174                 pLog->Record("ERROR:do_rk_partition_upgrade-->new CRKImage failed,%s!", szFw);
1175                 goto EXIT_DOWNLOAD;
1176             }
1177         }
1178     }
1179     else
1180     {
1181         pLog->Record("ERROR:do_rk_partition_upgrade-->IsDeviceLock failed!");
1182         goto EXIT_DOWNLOAD;
1183     }
1184     pDevice = new CRKAndroidDevice(device);
1185     if (!pDevice)
1186     {
1187         pLog->Record("ERROR:do_rk_partition_upgrade-->new CRKAndroidDevice failed!");
1188         goto EXIT_DOWNLOAD;
1189     }
1190     pDevice->SetObject(pImage, pComm, pLog);
1191     pDevice->m_pCallback = (UpgradeCallbackFunc)pCallback;
1192     pDevice->m_pProcessCallback = (UpgradeProgressCallbackFunc)pProgressCallback;
1193     bRet = pDevice->GetFlashInfo();
1194     if (!bRet)
1195     {
1196         pLog->Record("ERROR:do_rk_partition_upgrade-->GetFlashInfo failed!");
1197         goto EXIT_DOWNLOAD;
1198     }
1199     iRet = pComm->RKU_ShowNandLBADevice();
1200     pLog->Record("Info:do_rk_partition_upgrade-->RKU_ShowNandLBADevice ret=%d", iRet);
1201     iRet = pDevice->UpgradePartition();
1202     if (iRet != ERR_SUCCESS)
1203     {
1204         pLog->Record("ERROR:do_rk_partition_upgrade-->DownloadImage failed!");
1205         goto EXIT_DOWNLOAD;
1206     }
1207 
1208     bSuccess = true;
1209 EXIT_DOWNLOAD:
1210     if (bSuccess)
1211     {
1212         pLog->Record("Finish to upgrade partition.");
1213     }
1214     else
1215     {
1216         pLog->Record("Fail to upgrade partition!");
1217     }
1218     if (pLog)
1219     {
1220         delete pLog;
1221         pLog = NULL;
1222     }
1223     if (pImage)
1224     {
1225         delete pImage;
1226         pImage = NULL;
1227     }
1228     if (pDevice)
1229     {
1230         delete pDevice;
1231         pDevice = NULL;
1232     }
1233     else
1234     {
1235         if (pComm)
1236         {
1237             delete pComm;
1238             pComm = NULL;
1239         }
1240     }
1241 
1242     return bSuccess;
1243 }
1244 
do_rk_backup_recovery(void * pCallback,void * pProgressCallback)1245 bool do_rk_backup_recovery(void *pCallback, void *pProgressCallback)
1246 {
1247     bool bSuccess = false, bRet;
1248     int i, iRet;
1249     CRKLog *pLog = NULL;
1250     CRKComm *pComm = NULL;
1251     char *pParam = NULL;
1252     int nParamSize = -1;
1253     DWORD dwBackupOffset = 0;
1254     PARAM_ITEM_VECTOR vecParam;
1255     STRUCT_RKIMAGE_HDR hdr;
1256     const char *strPartSys = PARTNAME_SYSTEM;
1257 
1258     g_callback = (UpgradeCallbackFunc)pCallback;
1259     g_progress_callback = (UpgradeProgressCallbackFunc)pProgressCallback;
1260     if (g_progress_callback)
1261     {
1262         g_progress_callback(0.1, 10);
1263     }
1264     pLog = new CRKLog();
1265     if (!pLog)
1266     {
1267         goto EXIT_RECOVERY;
1268     }
1269     pLog->Record("Start to recovery from backup...");
1270 
1271     pComm = new CRKUsbComm(pLog);
1272     if (!pComm)
1273     {
1274         pLog->Record("ERROR:do_rk_backup_recovery-->new CRKComm failed!");
1275         goto EXIT_RECOVERY;
1276     }
1277     iRet = pComm->RKU_ShowNandLBADevice();
1278     pLog->Record("Info:do_rk_backup_recovery-->RKU_ShowNandLBADevice ret=%d", iRet);
1279     pLog->Record("Start to read parameter...");
1280     bRet = get_parameter_loader(pComm, pParam, nParamSize);
1281     if (bRet)
1282     {
1283         pParam = new char[nParamSize];
1284         if (pParam)
1285         {
1286             bRet = get_parameter_loader(pComm, pParam, nParamSize);
1287         }
1288     }
1289     if (!bRet)
1290     {
1291         pLog->Record("Read parameter failed!");
1292         goto EXIT_RECOVERY;
1293     }
1294     pLog->Record("Start to parse parameter...");
1295     bRet = parse_parameter(pParam, vecParam);
1296     if (!bRet)
1297     {
1298         pLog->Record("Parse parameter failed!");
1299         goto EXIT_RECOVERY;
1300     }
1301     for (i = 0; i < vecParam.size(); i++)
1302     {
1303         if (strcmp(vecParam[i].szItemName, PARTNAME_BACKUP) == 0)
1304         {
1305             dwBackupOffset = vecParam[i].uiItemOffset;
1306             break;
1307         }
1308     }
1309     if (dwBackupOffset == 0)
1310     {
1311         pLog->Record("Get backup offset failed!");
1312         goto EXIT_RECOVERY;
1313     }
1314     pLog->Record("Start to check firmware...");
1315     if (!check_fw_header(pComm, dwBackupOffset, &hdr, pLog))
1316     {
1317         pLog->Record("Check firmware header failed!");
1318         goto EXIT_RECOVERY;
1319     }
1320 
1321     if (!check_fw_crc(pComm, dwBackupOffset, &hdr, pLog))
1322     {
1323         pLog->Record("Check firmware crc failed!");
1324         goto EXIT_RECOVERY;
1325     }
1326 
1327     pLog->Record("Start to write system...");
1328 
1329     if (!download_backup_image(vecParam, (char *)strPartSys, dwBackupOffset, hdr, pComm, pLog))
1330     {
1331         pLog->Record("write system failed!");
1332         goto EXIT_RECOVERY;
1333     }
1334 
1335     bSuccess = true;
1336 
1337 EXIT_RECOVERY:
1338     if (bSuccess)
1339     {
1340         pLog->Record("Finish to recovery from backup.");
1341     }
1342     else
1343     {
1344         pLog->Record("Fail to recovery from backup!");
1345     }
1346     if (pParam)
1347     {
1348         delete []pParam;
1349         pParam = NULL;
1350     }
1351 
1352     if (pLog)
1353     {
1354         delete pLog;
1355         pLog = NULL;
1356     }
1357 
1358     if (pComm)
1359     {
1360         delete pComm;
1361         pComm = NULL;
1362     }
1363 
1364     return bSuccess;
1365 }
1366