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