/************************************************************************** * FUNCTION To Generate Hash by Chunk **************************************************************************/ static int sec_signfmt_image_read(ASF_FILE fp, char* part_name, uint32 seek_offset, char* read_buf, uint32 read_len) { uint32 read_sz = 0; uint32 ret = SEC_OK; #if DUMP_MORE_FOR_DEBUG SMSG(true,"[%s] Read image for length %d at offset 0x%x\n",MOD,read_len,seek_offset); #endif /* read from file */ if (ASF_FILE_NULL != fp) { ASF_SEEK_SET(fp, seek_offset*sizeof(char)); read_sz = ASF_READ(fp, read_buf, read_len); return read_sz; } /* read from mtd */ else { if(SEC_OK != (ret = sec_dev_read_image ( pl2part(part_name), (char*)read_buf, seek_offset, read_len, NORMAL_ROM))) { SMSG(true,"[%s] read mtd '%s' fail at image offset 0x%x with length 0x%x\n",MOD,(char*)pl2part(part_name),seek_offset,read_len); return 0; } return read_len; } }
/************************************************************************** * FUNCTION To Get Signature Length **************************************************************************/ unsigned int sec_signfmt_get_signature_length_v3(SECURE_IMG_INFO_V3 *img_if, ASF_FILE fp, SEC_IMG_HEADER *file_img_hdr, char *ext_buf) { uint32 crypto_hdr_offset = 0; uint32 read_sz = 0; SEC_EXTENSTION_CRYPTO ext_crypto; SEC_EXTENSTION_CRYPTO *ext_crypto_ptr = NULL; uint32 ext_crypto_size = sizeof(SEC_EXTENSTION_CRYPTO); /* get from seccfg's extension header */ if (ASF_FILE_NULL == fp) { ext_crypto_ptr = (SEC_EXTENSTION_CRYPTO *)(ext_buf + img_if->ext_offset + img_if->header.v3.signature_length); return get_signature_size((SEC_CRYPTO_SIGNATURE_TYPE)ext_crypto_ptr->sig_type); } /* get from file's extension header */ else { memset(&ext_crypto, 0x00, ext_crypto_size); /* seek to crypto header offset */ crypto_hdr_offset = file_img_hdr->signature_offset + file_img_hdr->signature_length; ASF_SEEK_SET(fp, crypto_hdr_offset); /* read crypto header */ if (ext_crypto_size != (read_sz = ASF_READ(fp, (char*)&ext_crypto, ext_crypto_size))) { SMSG(true,"[%s] read sz '%d' != '%d'\n",MOD,read_sz,ext_crypto_size); return -1; } return get_signature_size((SEC_CRYPTO_SIGNATURE_TYPE)ext_crypto.sig_type); } }
/************************************************************************** * READ IMAGE **************************************************************************/ uint32 sec_mtd_read_image(char* part_name, char* buf, uint32 off, uint32 size) { ASF_FILE fp; uint32 ret = SEC_OK; uint32 i = 0; char mtd_name[32]; uint32 part_index = 0; /* find which partition should be updated in mtd */ for(i=0; i<MAX_MTD_PARTITIONS; i++) { if(0 == mcmp(mtd_part_map[i].name,part_name,strlen(part_name))) { part_index = i; break; } } if(MAX_MTD_PARTITIONS == i) { ret = ERR_SBOOT_UPDATE_IMG_NOT_FOUND_IN_MTD; goto _end; } /* indicate which partition */ sprintf(mtd_name, "/dev/mtd/mtd%d", part_index); fp = ASF_OPEN(mtd_name); if (ASF_IS_ERR(fp)) { SMSG(true,"[%s] open fail\n",MOD); ret = ERR_SBOOT_UPDATE_IMG_OPEN_FAIL; goto _open_fail; } /* configure file system type */ osal_set_kernel_fs(); /* adjust read off */ ASF_SEEK_SET(fp,off); /* read image to input buf */ if(0 >= ASF_READ(fp,buf,size)) { ret = ERR_SBOOT_UPDATE_IMG_READ_FAIL; goto _read_fail; } _read_fail: ASF_CLOSE(fp); osal_restore_fs(); _open_fail: _end: return ret; }
/************************************************************************** * FUNCTION To check if the image is encrypted **************************************************************************/ int sec_cipherfmt_check_cipher(ASF_FILE fp, unsigned int start_off, unsigned int *img_len) { CIPHER_HEADER cipher_header; uint32 read_sz = 0; unsigned int ret = SEC_OK; ASF_GET_DS memset(&cipher_header, 0x00, CIPHER_IMG_HEADER_SIZE); if( !ASF_FILE_ERROR(fp) ) { ASF_SEEK_SET(fp, start_off); /* get header */ if (CIPHER_IMG_HEADER_SIZE != (read_sz = ASF_READ(fp, (char*)&cipher_header, CIPHER_IMG_HEADER_SIZE))) { SMSG(true,"[%s] read size '%d' != '%d'\n",MOD,read_sz,CIPHER_IMG_HEADER_SIZE); ret = ERR_IMAGE_CIPHER_READ_FAIL; goto _read_hdr_fail; } } else { SMSG(true,"[%s] file pointer is NULL\n",MOD); ret = ERR_IMAGE_CIPHER_IMG_NOT_FOUND; goto _img_hdr_not_found; } #if DUMP_MORE_FOR_DEBUG SMSG(true,"[%s] sec_cipherfmt_check_cipher - dump header\n",MOD); sec_cipherfmt_dump_buffer((char*)&cipher_header, CIPHER_IMG_HEADER_SIZE); #endif if( CIPHER_IMG_MAGIC != cipher_header.magic_number ) { SMSG(true,"[%s] magic number is wrong\n",MOD); ret = ERR_IMAGE_CIPHER_HEADER_NOT_FOUND; goto _img_hdr_not_found; } *img_len = cipher_header.image_length; _img_hdr_not_found: _read_hdr_fail: ASF_PUT_DS return ret; }
/************************************************************************** * FUNCTIONS To Verify File **************************************************************************/ int sec_signfmt_verify_file_v3(ASF_FILE fp, SEC_IMG_HEADER *img_hdr) { uint32 ret = SEC_OK; uint32 final_hash_sig_len = 0; uchar *final_hash_sig_buf = NULL; uint32 read_sz = 0; SEC_IMG_EXTENSTION_SET ext_set; uint32 ext_hdr_offset = 0; uint32 ext_hdr_len = 0; uchar *ext_hdr_buf = NULL; uint32 file_size = 0; uint32 hash_size = 0; uint32 sig_size = 0; uint32 i = 0; uchar *cal_hash_buf = NULL; uint32 cal_hash_buf_len = 0; uchar *tmp_ptr = NULL; uchar *verify_data = NULL; uint32 verify_data_len = 0; uint32 real_chunk_size = 0; /* ======================== */ /* init check */ /* ======================== */ #if DUMP_MORE_FOR_DEBUG SMSG(sec_info.bMsg,"[%s] Dump header ============> START\n",MOD); sec_signfmt_dump_buffer((uchar*)img_hdr,sizeof(SEC_IMG_HEADER)); SMSG(sec_info.bMsg,"[%s] Dump header ============> END\n",MOD); #endif if (SEC_IMG_MAGIC != img_hdr->magic_number) { SMSG(true,"[%s] magic number is invalid '0x%x'\n",MOD,img_hdr->magic_number); ret = ERR_SIGN_FORMAT_MAGIC_WRONG; goto _magic_wrong_err; } if (SEC_EXTENSION_MAGIC != img_hdr->sign_offset) { SMSG(true,"[%s] extension magic number is invalid '0x%x'\n",MOD,img_hdr->sign_offset); ret = ERR_SIGN_FORMAT_MAGIC_WRONG; goto _magic_wrong_err; } /* ======================== */ /* locate final signature and hash */ /* ======================== */ final_hash_sig_len = img_hdr->signature_length; final_hash_sig_buf = (uchar*)ASF_MALLOC(final_hash_sig_len); if (NULL == final_hash_sig_buf) { ret = ERR_FS_READ_BUF_ALLOCATE_FAIL; goto _malloc_hash_sig_fail; } ASF_SEEK_SET(fp, img_hdr->signature_offset); if (final_hash_sig_len != (read_sz = ASF_READ(fp, final_hash_sig_buf, final_hash_sig_len))) { SMSG(true,"[%s] read size '%d' != '%d'\n",MOD,read_sz,final_hash_sig_len); ret = ERR_FS_READ_SIZE_FAIL; goto _read_hash_sig_fail; } #if DUMP_MORE_FOR_DEBUG SMSG(sec_info.bMsg,"[%s] Dump sign and hash value ============> START\n",MOD); sec_signfmt_dump_buffer(final_hash_sig_buf,final_hash_sig_len); SMSG(sec_info.bMsg,"[%s] Dump sign and hash value ============> END\n",MOD); #endif /* read file size */ ASF_SEEK_END(fp, 0); file_size = ASF_FILE_POS(fp); /* ======================== */ /* search for extension header */ /* ======================== */ memset(&ext_set, 0x00, sizeof(SEC_IMG_EXTENSTION_SET)); ext_hdr_offset = SEC_IMG_HEADER_SIZE + img_hdr->image_length + img_hdr->signature_length; ext_hdr_len = file_size - ext_hdr_offset; ext_hdr_buf = (uchar*)ASF_MALLOC(ext_hdr_len); if (NULL == ext_hdr_buf) { ret = ERR_FS_READ_BUF_ALLOCATE_FAIL; goto _malloc_ext_hdr_fail; } ASF_SEEK_SET(fp, ext_hdr_offset); if (ext_hdr_len != (read_sz = ASF_READ(fp, ext_hdr_buf, ext_hdr_len))) { SMSG(true,"[%s] read size '%d' != '%d'\n",MOD,read_sz,ext_hdr_len); ret = ERR_FS_READ_SIZE_FAIL; goto _read_ext_hdr_fail; } if( SEC_OK != (ret = sec_signfmt_search_extension(ext_hdr_buf, ext_hdr_len, &ext_set)) ) { SMSG(true,"[%s] Image extension header not found\n",MOD); goto _ext_hdr_search_fail; } hash_size = get_hash_size((SEC_CRYPTO_HASH_TYPE)ext_set.crypto->hash_type); sig_size = get_signature_size((SEC_CRYPTO_SIGNATURE_TYPE)ext_set.crypto->sig_type); #if DUMP_MORE_FOR_DEBUG SMSG(sec_info.bMsg,"[%s] Dump ext hash value ============> START\n",MOD); for(i=0;i<ext_set.frag->frag_count;i++) { SMSG(sec_info.bMsg,"[%s] Dump EXT hash [%d]\n",MOD,i); sec_signfmt_dump_buffer(ext_set.hash_only[i]->hash_data,hash_size); } SMSG(sec_info.bMsg,"[%s] Dump ext hash value ============> END\n",MOD); #endif /* ======================== */ /* calculate each hash by chunk */ /* ======================== */ cal_hash_buf_len = hash_size*ext_set.frag->frag_count; cal_hash_buf = (uchar*)ASF_MALLOC(cal_hash_buf_len); if (NULL == cal_hash_buf) { ret = ERR_FS_READ_BUF_ALLOCATE_FAIL; goto _malloc_cal_buf_fail; } memset(cal_hash_buf, 0x00, cal_hash_buf_len); #if DUMP_MORE_FOR_DEBUG SMSG(sec_info.bMsg,"[%s] dump reset data\n",MOD); sec_signfmt_dump_buffer(cal_hash_buf,cal_hash_buf_len); #endif tmp_ptr = cal_hash_buf; #if DUMP_MORE_FOR_DEBUG SMSG(sec_info.bMsg,"[%s] Total cal hash length is %d\n",MOD,cal_hash_buf_len); #endif for(i=0;i<ext_set.frag->frag_count;i++) { memset(tmp_ptr, 0x00, hash_size); if(ext_set.frag->chunk_size == 0) { real_chunk_size = ext_set.hash_only[i]->hash_len; } else { real_chunk_size = ext_set.frag->chunk_size; } if(sec_signfmt_gen_hash_by_chunk(fp, NULL, SEC_IMG_HEADER_SIZE+ext_set.hash_only[i]->hash_offset, ext_set.hash_only[i]->hash_len, tmp_ptr, ext_set.hash_only[i]->sub_type, real_chunk_size)!=0) { ret = ERR_SIGN_FORMAT_CAL_HASH_BY_CHUNK_FAIL; goto _gen_hash_by_chunk_fail; } #if DUMP_MORE_FOR_DEBUG SMSG(sec_info.bMsg,"[%s] Dump CAL hash right after: [%d], offset is 0x%x\n",MOD,i,tmp_ptr); sec_signfmt_dump_buffer(cal_hash_buf,cal_hash_buf_len); #endif tmp_ptr += hash_size; } #if DUMP_MORE_FOR_DEBUG SMSG(sec_info.bMsg,"[%s] Dump CAL hash right after all done, offset is 0x%x\n",MOD,tmp_ptr); sec_signfmt_dump_buffer(cal_hash_buf,cal_hash_buf_len); #endif #if DUMP_MORE_FOR_DEBUG SMSG(sec_info.bMsg,"[%s] Dump cal hash value ============> START\n",MOD); tmp_ptr = cal_hash_buf; for(i=0;i<ext_set.frag->frag_count;i++) { SMSG(sec_info.bMsg,"[%s] Dump CAL hash [%d]\n",MOD,i); sec_signfmt_dump_buffer(tmp_ptr,hash_size); tmp_ptr += hash_size; } SMSG(sec_info.bMsg,"[%s] Dump cal hash value ============> END\n",MOD); #endif /* ======================== */ /* compose final verify buffer */ /* ======================== */ verify_data_len = SEC_IMG_HEADER_SIZE+cal_hash_buf_len+ext_hdr_len; verify_data = (uchar*)ASF_MALLOC(verify_data_len); if (NULL == cal_hash_buf) { ret = ERR_FS_READ_BUF_ALLOCATE_FAIL; goto _malloc_verify_buf_fail; } tmp_ptr = verify_data; /* copy header */ mcpy(tmp_ptr,img_hdr,SEC_IMG_HEADER_SIZE); tmp_ptr += SEC_IMG_HEADER_SIZE; /* copy cal hash */ for(i=0;i<ext_set.frag->frag_count;i++) { mcpy(tmp_ptr,cal_hash_buf+i*hash_size,hash_size); tmp_ptr += hash_size; } /* copy extension header */ mcpy(tmp_ptr,ext_hdr_buf,ext_hdr_len); #if DUMP_MORE_FOR_DEBUG SMSG(sec_info.bMsg,"[%s] Dump verify data (%d):\n",MOD,verify_data_len); sec_signfmt_dump_buffer(verify_data,verify_data_len); #endif #if DUMP_MORE_FOR_DEBUG SMSG(sec_info.bMsg,"[%s] Dump signature data (%d):\n",MOD,sig_size); sec_signfmt_dump_buffer(final_hash_sig_buf,sig_size); #endif osal_verify_lock(); /* ======================== */ /* verify buffer */ /* ======================== */ SMSG(sec_info.bMsg,"[%s] verify (lock)... \n",MOD); if(SEC_OK != (ret = sec_verify(verify_data, verify_data_len, final_hash_sig_buf, sig_size ))) { osal_verify_unlock(); SMSG(true,"[%s] verify fail (unlock), ret is %d\n\n",MOD,ret); goto _verify_fail; } osal_verify_unlock(); SMSG(sec_info.bMsg,"[%s] verify pass (unlock)\n\n",MOD); _verify_fail: ASF_FREE(verify_data); _malloc_verify_buf_fail: _gen_hash_by_chunk_fail: ASF_FREE(cal_hash_buf); _malloc_cal_buf_fail: _ext_hdr_search_fail: _read_ext_hdr_fail: ASF_FREE(ext_hdr_buf); _malloc_ext_hdr_fail: _read_hash_sig_fail: ASF_FREE(final_hash_sig_buf); _malloc_hash_sig_fail: _magic_wrong_err: return ret; }
/************************************************************************** * READ SECRO **************************************************************************/ uint32 sec_fs_read_secroimg (char* path, char* buf) { uint32 ret = SEC_OK; const uint32 size = sizeof(AND_SECROIMG_T); uint32 temp = 0; ASF_FILE fd; /* ------------------------ */ /* check parameter */ /* ------------------------ */ SMSG(TRUE,"[%s] open '%s'\n",MOD,path); if(0 == size) { ret = ERR_FS_SECRO_READ_SIZE_CANNOT_BE_ZERO; goto _end; } /* ------------------------ */ /* open secro */ /* ------------------------ */ fd = ASF_OPEN(path); if (ASF_IS_ERR(fd)) { ret = ERR_FS_SECRO_OPEN_FAIL; goto _open_fail; } /* ------------------------ */ /* read secro */ /* ------------------------ */ /* configure file system type */ osal_set_kernel_fs(); /* adjust read off */ ASF_SEEK_SET(fd,0); /* read secro content */ if(0 >= (temp = ASF_READ(fd,buf,size))) { ret = ERR_FS_SECRO_READ_FAIL; goto _end; } if(size != temp) { SMSG(TRUE,"[%s] size '0x%x', read '0x%x'\n",MOD,size,temp); ret = ERR_FS_SECRO_READ_WRONG_SIZE; goto _end; } /* ------------------------ */ /* check integrity */ /* ------------------------ */ if(SEC_OK != (ret = sec_secro_check())) { goto _end; } /* ------------------------ */ /* SECROIMG is valid */ /* ------------------------ */ bSecroExist = TRUE; _end: ASF_CLOSE(fd); osal_restore_fs(); _open_fail: return ret; }
int read_info (int part_index, uint32 part_off, uint32 search_region, char* info_name, uint32 info_name_len, uint32 info_sz, char* info_buf) { int ret = ERR_MTD_INFO_NOT_FOUND; char part_path[32]; uint32 off = 0; uchar *buf; MtdRCtx *ctx = (MtdRCtx*) osal_kmalloc(sizeof(MtdRCtx)); if (ctx == NULL) { ret = ERR_ROM_INFO_ALLOCATE_BUF_FAIL; goto _end; } ctx->buf = osal_kmalloc(search_region); memset(ctx->buf,0,search_region); if (ctx->buf == NULL) { ret = ERR_ROM_INFO_ALLOCATE_BUF_FAIL; goto _end; } /* ------------------------ */ /* open file */ /* ------------------------ */ /* in order to keep key finding process securely, open file in kernel module */ if(TRUE == sec_usif_enabled()) { sec_usif_part_path(part_index,part_path,sizeof(part_path)); if(FALSE == dump_search_info) { SMSG(TRUE,"[%s] open '%s'\n",MOD,part_path); dump_search_info = TRUE; } } else { sprintf(part_path, "/dev/mtd/mtd%d", part_index); if(FALSE == dump_search_info) { SMSG(TRUE,"[%s] open '%s'\n",MOD,part_path); dump_search_info = TRUE; } } ctx->fd = ASF_OPEN(part_path); if (ASF_IS_ERR(ctx->fd)) { SMSG(true,"[%s] open fail\n",MOD); ret = ERR_INFO_PART_NOT_FOUND; goto _open_fail; } /* ------------------------ */ /* read partition */ /* ------------------------ */ /* configure file system type */ osal_set_kernel_fs(); /* adjust read off */ ASF_SEEK_SET(ctx->fd,part_off); /* read partition */ if(0 >= (ret = ASF_READ(ctx->fd,ctx->buf,search_region))) { SMSG(TRUE,"[%s] read fail (%d)\n",MOD,ret); ret = ERR_ROM_INFO_MTD_READ_FAIL; goto _end; } else { /* ------------------------ */ /* search info */ /* ------------------------ */ for(off = 0; off<(search_region-info_sz); off++) { buf = ctx->buf + off; if(0 == strncmp(buf,info_name,info_name_len)) { osal_mtd_lock(); /* ------------------------ */ /* fill info */ /* ------------------------ */ mcpy(info_buf, buf, info_sz); ret = SEC_OK; osal_mtd_unlock(); break; } } } _end: ASF_CLOSE(ctx->fd); osal_restore_fs(); _open_fail : osal_kfree(ctx->buf); osal_kfree(ctx); return ret; }
void sec_dev_find_parts(void) { ASF_FILE fd; const uint32 buf_len = 2048; char *buf = osal_kmalloc(buf_len); char *pmtdbufp; uint32 mtd_part_cnt = 0; uint32 off = 0; uint32 rn = 0; ssize_t pm_sz; int cnt; osal_set_kernel_fs(); /* -------------------------- */ /* open proc device */ /* -------------------------- */ if(TRUE == sec_usif_enabled()) { /* -------------------------- */ /* open proc/dumchar_info */ /* -------------------------- */ SMSG(TRUE,"[%s] open /proc/dumchar_info\n",MOD); fd = ASF_OPEN("/proc/dumchar_info"); } else { /* -------------------------- */ /* open proc/mtd */ /* -------------------------- */ SMSG(TRUE,"[%s] open /proc/mtd\n",MOD); fd = ASF_OPEN("/proc/mtd"); } if (ASF_IS_ERR(fd)) { goto _end; } buf[buf_len - 1] = '\0'; pm_sz = ASF_READ(fd, buf, buf_len - 1); pmtdbufp = buf; /* -------------------------- */ /* parsing proc device */ /* -------------------------- */ while (pm_sz > 0) { int m_num, m_sz, mtd_e_sz; char m_name[16]; m_name[0] = '\0'; m_num = -1; m_num ++; if(TRUE == sec_usif_enabled()) { /* -------------------------- */ /* parsing proc/dumchar_info */ /* -------------------------- */ cnt = sscanf(pmtdbufp, "%15s %x %x %x",m_name, &m_sz, &mtd_e_sz, &rn); //SMSG(TRUE,"[%s] find parts %s, size 0x%x, cnt 0x%x, rn 0x%x\n",MOD,m_name,m_sz,cnt,rn); if ((cnt == 4) && (rn == 2)) { if (mtd_part_cnt < MAX_MTD_PARTITIONS) { /* ===================== */ /* uboot */ /* ===================== */ if(0 == mcmp(m_name,USIF_UBOOT,strlen(USIF_UBOOT))) { mcpy(mtd_part_map[mtd_part_cnt].name, PL_UBOOT, strlen(PL_UBOOT)); } /* ===================== */ /* logo */ /* ===================== */ else if(0 == mcmp(m_name,USIF_LOGO,strlen(USIF_LOGO))) { mcpy(mtd_part_map[mtd_part_cnt].name, PL_LOGO, strlen(PL_LOGO)); } /* ===================== */ /* boot image */ /* ===================== */ else if(0 == mcmp(m_name,USIF_BOOTIMG,strlen(USIF_BOOTIMG))) { mcpy(mtd_part_map[mtd_part_cnt].name, PL_BOOTIMG, strlen(PL_BOOTIMG)); } /* ===================== */ /* user data */ /* ===================== */ else if(0 == mcmp(m_name,USIF_USER,strlen(USIF_USER))) { mcpy(mtd_part_map[mtd_part_cnt].name, PL_USER, strlen(PL_USER)); } /* ===================== */ /* android system image */ /* ===================== */ else if(0 == mcmp(m_name,USIF_ANDSYSIMG,strlen(USIF_ANDSYSIMG))) { mcpy(mtd_part_map[mtd_part_cnt].name, PL_ANDSYSIMG, strlen(PL_ANDSYSIMG)); } /* ===================== */ /* recovery */ /* ===================== */ else if(0 == mcmp(m_name,USIF_RECOVERY,strlen(USIF_RECOVERY))) { mcpy(mtd_part_map[mtd_part_cnt].name, PL_RECOVERY, strlen(PL_RECOVERY)); } /* ===================== */ /* secroimg */ /* ===================== */ else if(0 == mcmp(m_name,USIF_SECRO,strlen(USIF_SECRO))) { mcpy(mtd_part_map[mtd_part_cnt].name, PL_SECRO, strlen(PL_SECRO)); secro_img_mtd_num = mtd_part_cnt; } /* ===================== */ /* other */ /* ===================== */ else { mcpy(mtd_part_map[mtd_part_cnt].name, m_name, sizeof(m_name)-1); } /* fill partition size */ mtd_part_map[mtd_part_cnt].sz = m_sz; /* calculate partition off */ mtd_part_map[mtd_part_cnt].off = off; /* update off and part count */ off += m_sz; mtd_part_cnt++; } else { SMSG(TRUE,"too many mtd partitions\n"); } } } else { /* -------------------------- */ /* parsing proc/mtd */ /* -------------------------- */ cnt = sscanf(pmtdbufp, "mtd%d: %x %x %15s",&m_num, &m_sz, &mtd_e_sz, m_name); if ((cnt == 4) && (m_name[0] == '"')) { char *x = strchr(m_name + 1, '"'); if (x) { *x = 0; } if (mtd_part_cnt < MAX_MTD_PARTITIONS) { /* ===================== */ /* uboot */ /* ===================== */ if(0 == mcmp(m_name+1,MTD_UBOOT,strlen(MTD_UBOOT))) { mcpy(mtd_part_map[mtd_part_cnt].name, PL_UBOOT, strlen(PL_UBOOT)); } /* ===================== */ /* logo */ /* ===================== */ else if(0 == mcmp(m_name+1,MTD_LOGO,strlen(MTD_LOGO))) { mcpy(mtd_part_map[mtd_part_cnt].name, PL_LOGO, strlen(PL_LOGO)); } /* ===================== */ /* boot image */ /* ===================== */ else if(0 == mcmp(m_name+1,MTD_BOOTIMG,strlen(MTD_BOOTIMG))) { mcpy(mtd_part_map[mtd_part_cnt].name, PL_BOOTIMG, strlen(PL_BOOTIMG)); } /* ===================== */ /* user data */ /* ===================== */ else if(0 == mcmp(m_name+1,MTD_USER,strlen(MTD_USER))) { mcpy(mtd_part_map[mtd_part_cnt].name, PL_USER, strlen(PL_USER)); } /* ===================== */ /* android system image */ /* ===================== */ else if(0 == mcmp(m_name+1,MTD_ANDSYSIMG,strlen(MTD_ANDSYSIMG))) { mcpy(mtd_part_map[mtd_part_cnt].name, PL_ANDSYSIMG, strlen(PL_ANDSYSIMG)); } /* ===================== */ /* recovery */ /* ===================== */ else if(0 == mcmp(m_name+1,MTD_RECOVERY,strlen(MTD_RECOVERY))) { mcpy(mtd_part_map[mtd_part_cnt].name, PL_RECOVERY, strlen(PL_RECOVERY)); } /* ===================== */ /* secroimg */ /* ===================== */ else if(0 == mcmp(m_name+1,MTD_SECRO,strlen(MTD_SECRO))) { mcpy(mtd_part_map[mtd_part_cnt].name, PL_SECRO, strlen(PL_SECRO)); secro_img_mtd_num = mtd_part_cnt; } /* ===================== */ /* other */ /* ===================== */ else { mcpy(mtd_part_map[mtd_part_cnt].name, m_name+1, sizeof(m_name)-1); } /* fill partition size */ mtd_part_map[mtd_part_cnt].sz = m_sz; /* calculate partition off */ mtd_part_map[mtd_part_cnt].off = off; /* update off and part count */ off += m_sz; mtd_part_cnt++; } else { SMSG(TRUE,"too many mtd partitions\n"); } } } while (pm_sz > 0 && *pmtdbufp != '\n') { pmtdbufp++; pm_sz--; } if (pm_sz > 0) { pmtdbufp++; pm_sz--; } } ASF_CLOSE(fd); _end: osal_kfree(buf); osal_restore_fs(); /* ------------------------ */ /* dump partition */ /* ------------------------ */ //sec_dev_dump_part(); }
/************************************************************************** * FUNCTION To decrypt the cipher content **************************************************************************/ int sec_cipherfmt_decrypted(ASF_FILE fp, unsigned int start_off, char *buf, unsigned int buf_len, unsigned int *data_offset) { unsigned int ret = SEC_OK; CIPHER_HEADER cipher_header; uint32 read_sz = 0; uint32 read_offset = start_off; char *buf_ptr = buf; uint32 total_len = 0; uint32 end_pos; char tmp_buf[CIPHER_BLOCK_SIZE]; char tmp_buf2[CIPHER_BLOCK_SIZE]; uint32 try_read_len = 0; ASF_GET_DS SMSG(true,"[%s] sec_cipherfmt_decrypted - start offset is %d (0x%x)\n",MOD, start_off, start_off); SMSG(true,"[%s] sec_cipherfmt_decrypted - total buffer length %d (0x%x)\n",MOD, buf_len, buf_len); memset(&cipher_header, 0x00, CIPHER_IMG_HEADER_SIZE); if( !ASF_FILE_ERROR(fp) ) { ASF_SEEK_SET(fp, read_offset); /* get header */ if (CIPHER_IMG_HEADER_SIZE != (read_sz = ASF_READ(fp, (char*)&cipher_header, CIPHER_IMG_HEADER_SIZE))) { SMSG(true,"[%s] read size '%d' != '%d'\n",MOD,read_sz,CIPHER_IMG_HEADER_SIZE); ret = ERR_IMAGE_CIPHER_READ_FAIL; goto _read_hdr_fail; } } else { SMSG(true,"[%s] file pointer is NULL\n",MOD); ret = ERR_IMAGE_CIPHER_IMG_NOT_FOUND; goto _read_hdr_fail; } if( CIPHER_IMG_MAGIC != cipher_header.magic_number ) { SMSG(true,"[%s] file pointer is NULL\n",MOD); ret = ERR_IMAGE_CIPHER_HEADER_NOT_FOUND; goto _hdr_not_found; } #if DUMP_MORE_FOR_DEBUG SMSG(true,"[%s] sec_cipherfmt_decrypted - dump header\n",MOD); sec_cipherfmt_dump_buffer((char*)&cipher_header, CIPHER_IMG_HEADER_SIZE); #endif read_offset += CIPHER_IMG_HEADER_SIZE; ASF_SEEK_SET(fp, read_offset); total_len = cipher_header.image_length; SMSG(true,"[%s] sec_cipherfmt_decrypted - cipher_offset is %d (0x%x)\n",MOD, cipher_header.cipher_offset, cipher_header.cipher_offset); SMSG(true,"[%s] sec_cipherfmt_decrypted - cipher_length %d (0x%x)\n",MOD, cipher_header.cipher_length, cipher_header.cipher_length); /* by pass cipher offset, cause this part is not encrypted */ if( cipher_header.cipher_offset ) { /* get header */ if (cipher_header.cipher_offset != (read_sz = ASF_READ(fp, (char*)buf_ptr, cipher_header.cipher_offset))) { SMSG(true,"[%s] read start size '%d' != '%d'\n",MOD,read_sz,cipher_header.cipher_offset); ret = ERR_IMAGE_CIPHER_READ_FAIL; goto _read_cipher_offset_fail; } #if DUMP_MORE_FOR_DEBUG SMSG(true,"[%s] sec_cipherfmt_decrypted - dump head part: 0x%x\n",MOD, read_offset); sec_cipherfmt_dump_buffer(buf_ptr, cipher_header.cipher_offset); #endif read_offset += cipher_header.cipher_offset; buf_ptr += cipher_header.cipher_offset; total_len -= cipher_header.cipher_offset; } ASF_SEEK_SET(fp, read_offset); /* decrypted the cipher content */ if( cipher_header.cipher_length ) { end_pos = read_offset + cipher_header.cipher_length; /* init the key */ ret = sec_aes_init(); if (ret) { SMSG(true,"[%s] key init failed!\n",MOD); ret = ERR_IMAGE_CIPHER_KEY_ERR; goto _key_init_fail; } /* read with fixed block size */ while( read_offset < end_pos ) { if( (end_pos - read_offset) < CIPHER_BLOCK_SIZE ) { SMSG(true,"[%s] cipher block size is not aligned (warning!)\n",MOD); try_read_len = end_pos - read_offset; break; } memset(tmp_buf, 0x00, CIPHER_BLOCK_SIZE); if (CIPHER_BLOCK_SIZE != (read_sz = ASF_READ(fp, (char*)tmp_buf, CIPHER_BLOCK_SIZE))) { SMSG(true,"[%s] read cipher size '%d' != '%d'(try)\n",MOD,read_sz,CIPHER_BLOCK_SIZE); ret = ERR_IMAGE_CIPHER_READ_FAIL; goto _read_cipher_size_wrong; } #if DUMP_MORE_FOR_DEBUG SMSG(true,"[%s] sec_cipherfmt_decrypted - dump cipher part: 0x%x\n",MOD, read_offset); sec_cipherfmt_dump_buffer(tmp_buf, CIPHER_BLOCK_SIZE); #endif ret = lib_aes_dec(tmp_buf, CIPHER_BLOCK_SIZE, buf_ptr, CIPHER_BLOCK_SIZE); if (ret) { SMSG(true,"[%s] dec cipher block fail\n",MOD); ret = ERR_IMAGE_CIPHER_DEC_Fail; goto _decrypt_fail; } #if DUMP_MORE_FOR_DEBUG SMSG(true,"[%s] sec_cipherfmt_decrypted - dump decipher part: 0x%x\n",MOD, read_offset); sec_cipherfmt_dump_buffer(buf_ptr, CIPHER_BLOCK_SIZE); #endif read_offset += CIPHER_BLOCK_SIZE; buf_ptr += CIPHER_BLOCK_SIZE; total_len -= CIPHER_BLOCK_SIZE; } /* read with remain block size */ if( try_read_len ) { memset(tmp_buf, 0x00, CIPHER_BLOCK_SIZE); if (try_read_len != (read_sz = ASF_READ(fp, (char*)tmp_buf, try_read_len))) { SMSG(true,"[%s] read cipher size '%d' != '%d'(remain)\n",MOD,read_sz,try_read_len); ret = ERR_IMAGE_CIPHER_READ_FAIL; goto _read_cipher_size_wrong; } #if DUMP_MORE_FOR_DEBUG SMSG(true,"[%s] sec_cipherfmt_decrypted - dump cipher part: 0x%x (try)\n",MOD, read_offset); sec_cipherfmt_dump_buffer(tmp_buf, try_read_len); #endif ret = lib_aes_dec(tmp_buf, CIPHER_BLOCK_SIZE, tmp_buf2, CIPHER_BLOCK_SIZE); if (ret) { SMSG(true,"[%s] dec cipher block fail\n",MOD); ret = ERR_IMAGE_CIPHER_DEC_Fail; goto _decrypt_fail; } memcpy(buf_ptr, tmp_buf2, try_read_len); #if DUMP_MORE_FOR_DEBUG SMSG(true,"[%s] sec_cipherfmt_decrypted - dump decipher part: 0x%x (try)\n",MOD, read_offset); sec_cipherfmt_dump_buffer(buf_ptr, try_read_len); #endif read_offset += try_read_len; buf_ptr += try_read_len; total_len -= try_read_len; } } /* read final plain text part, cause this part is not encrypted */ if( total_len > 0 ) { if (total_len != (read_sz = ASF_READ(fp, (char*)buf_ptr, total_len))) { SMSG(true,"[%s] read tail size '%d' != '%d'\n",MOD,read_sz,total_len); ret = ERR_IMAGE_CIPHER_READ_FAIL; goto _read_tail_fail; } #if DUMP_MORE_FOR_DEBUG SMSG(true,"[%s] sec_cipherfmt_decrypted - dump tail part: 0x%x\n",MOD, read_offset); sec_cipherfmt_dump_buffer(buf_ptr, total_len); #endif read_offset += total_len; buf_ptr += total_len; total_len -= total_len; } if( total_len != 0 ) { SMSG(true,"[%s] image size is not correct\n",MOD); ret = ERR_IMAGE_CIPHER_WRONG_OPERATION; goto _image_size_wrong; } *data_offset = CIPHER_IMG_HEADER_SIZE; SMSG(true,"[%s] image descrypted successful\n",MOD); _image_size_wrong: _read_tail_fail: _decrypt_fail: _read_cipher_size_wrong: _key_init_fail: _read_cipher_offset_fail: _hdr_not_found: _read_hdr_fail: ASF_PUT_DS return ret; }