/************************************************************************** * FUNCTION To Get Hash Length **************************************************************************/ unsigned int sec_signfmt_get_hash_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_hash_size((SEC_CRYPTO_HASH_TYPE)ext_crypto_ptr->hash_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_hash_size((SEC_CRYPTO_HASH_TYPE)ext_crypto.hash_type); } }
int config_header_v1_v2_chk(SEC_IMG_HEADER *sec_hdr) { sec_hdr->sig_len = get_sigature_size(g_sig_type)+get_hash_size(g_hash_type); /* ------------------------------------- */ /* check sign length */ /* ------------------------------------- */ /* check if the whole image should be signed */ if(0 == sec_hdr->s_len) { sec_hdr->s_len = sec_hdr->img_len - sec_hdr->s_off; } /* check if sign offset is greater than image length */ if(sec_hdr->img_len <= sec_hdr->s_off) { MSG("[%s] IMG len (%d) <= sign off (%d)\n",MOD, sec_hdr->img_len, sec_hdr->s_off); MSG("[%s] Invalid sign off\n",MOD); return -1; } /* check if sign length is greater than image length */ if(sec_hdr->img_len < (sec_hdr->s_len + sec_hdr->s_off)) { MSG("[%s] IMG len (%d) < sign len (%d) + sign off (%d)\n",MOD, sec_hdr->img_len, sec_hdr->s_len, sec_hdr->s_off); sec_hdr->s_len = sec_hdr->img_len - sec_hdr->s_off; MSG("[%s] adjust sign len to (%d)\n",MOD,sec_hdr->s_len); } return 0; }
/************************************************************************** * FUNCTION To Search Extension Header **************************************************************************/ static uint32 sec_signfmt_search_extension(uchar *ext, uint32 ext_len, SEC_IMG_EXTENSTION_SET *ext_set) { SEC_EXTENSTION_END_MARK *search_pattern; uchar *d_ptr,*end_ptr; uint32 hash_only_idx = 0; #if DUMP_MORE_FOR_DEBUG SMSG(sec_info.bMsg,"[%s] Dump extension data ============> START\n",MOD); sec_signfmt_dump_buffer(ext,ext_len); SMSG(sec_info.bMsg,"[%s] Dump extension data ============> END\n",MOD); #endif end_ptr = ext + ext_len; d_ptr = ext; while( d_ptr < end_ptr ) { search_pattern = (SEC_EXTENSTION_END_MARK *)d_ptr; if(search_pattern->magic!=SEC_EXTENSION_HEADER_MAGIC) { SMSG(true,"[%s] Image extension header magic wrong\n",MOD); return ERR_SIGN_FORMAT_EXT_HDR_MAGIC_WRONG; } switch(search_pattern->ext_type) { case SEC_EXT_HDR_CRYPTO: ext_set->crypto = (SEC_EXTENSTION_CRYPTO *)d_ptr; d_ptr += sizeof(SEC_EXTENSTION_CRYPTO); break; case SEC_EXT_HDR_FRAG_CFG: ext_set->frag = (SEC_FRAGMENT_CFG *)d_ptr; d_ptr += sizeof(SEC_FRAGMENT_CFG); ext_set->hash_only = (SEC_EXTENSTION_HASH_ONLY **)ASF_MALLOC(ext_set->frag->frag_count*sizeof(SEC_EXTENSTION_HASH_ONLY *)); break; case SEC_EXT_HDR_HASH_ONLY: ext_set->hash_only[hash_only_idx] = (SEC_EXTENSTION_HASH_ONLY *)d_ptr; d_ptr += sizeof(SEC_EXTENSTION_HASH_ONLY) + get_hash_size(ext_set->hash_only[hash_only_idx]->sub_type); hash_only_idx++; break; case SEC_EXT_HDR_END_MARK: ext_set->end = (SEC_EXTENSTION_END_MARK *)d_ptr; d_ptr += sizeof(SEC_EXTENSTION_END_MARK); break; case SEC_EXT_HDR_HASH_SIG: default: SMSG(true,"[%s] Image header type not support %d\n",MOD,search_pattern->ext_type); return ERR_SIGN_FORMAT_EXT_TYPE_NOT_SUPPORT; } } if( ext_set->crypto == NULL || ext_set->frag == NULL || ext_set->hash_only == NULL || ext_set->end == NULL) { SMSG(true,"[%s] Some header is not searched\n",MOD); return ERR_SIGN_FORMAT_EXT_HDR_NOT_FOUND; } return SEC_OK; }
/* Used in fork case, to avoid deadlocks. * The fork caller acquires all locks before fork and release them * after because the child will have only a thread. If one lock is * taken by another thread than, in the child process, nobody will * release it. */ static void acquire_locks(void) { struct entries_list *list; struct hashentry *tmp; struct shm_data *data; struct semid_pool *semaptr; int i; SYSV_MUTEX_LOCK(&lock_undo); SYSV_MUTEX_LOCK(&lock_resources); //pthread_rwlock_wrlock(&rwlock_addrs); for (i=0; i<get_hash_size(MAXSIZE); i++) { list = &shmaddrs->entries[i]; if (LIST_EMPTY(list)) continue; LIST_FOREACH(tmp, list, entry_link) { data = (struct shm_data*)tmp->value; if (data->type == SEMGET) { semaptr = (struct semid_pool *)data->internal; #ifdef SYSV_RWLOCK #ifdef SYSV_SEMS /* There is no need to acquire the mutexes from * each semaphore in the group. It is enough * to acquire the group lock in write mode. */ #endif sysv_rwlock_wrlock(&semaptr->rwlock); #else sysv_mutex_lock(&semaptr->mutex); #endif } } }
void load_variables(HWND parent, int verbose, int novalue, CStringMapInt &vars) { CString filename; int fhandle; int len; CString area, var; char line[44]; if(pst_compatible_var()) { if(file_exists(filename) ) { if(MessageBox(parent, filename+" exists, shall I load it instead of var.var?","Variables",MB_YESNO)==IDNO) { filename=bgfolder+"var.var"; } } else filename=bgfolder+"var.var"; } else filename=bgfolder+"itemchecker.var"; fhandle=open(filename,O_RDONLY|O_BINARY); if(fhandle<1) { if(verbose) MessageBox(parent, "Cannot load "+filename,"Error",MB_OK); return; } len=filelength(fhandle); if((len<44) || (len%44) ) { MessageBox(parent, "Crippled file:"+filename,"Error",MB_OK); close(fhandle); return; } len/=44; vars.RemoveAll(); vars.InitHashTable(get_hash_size(len*2)); read(fhandle,line,44); //skipping first fake line while(--len) { read(fhandle,line,44); area.Format("%.6s",line); var.Format("%.32s",line+8); area.MakeUpper(); var.TrimRight(); var.MakeUpper(); if(novalue) vars[area+var]=2; else vars[area+var]=*(long *) (&line[40]); } close(fhandle); }
int config_header_v3_chk(SEC_IMG_HEADER *sec_hdr) { int i; SEC_EXTENTION_CFG *p_ext_cfg = (SEC_EXTENTION_CFG *)get_ext_cfg(); unsigned min_pos = 0; unsigned max_pos = sec_hdr->img_len; unsigned region_end = 0; DBG("[%s] sec_hdr->img_len = %d\n", MOD, sec_hdr->img_len); sec_hdr->sig_len = get_sigature_size(g_sig_type)+get_hash_size(g_hash_type); sec_hdr->s_off = SEC_EXTENSION_MAGIC; sec_hdr->s_len = SEC_EXTENSION_MAGIC; if(p_ext_cfg->verify_count == 0) { MSG("[%s] Sign region count is zero, please check config file(v3)\n",MOD); return -1; } /* check for chunk size 0 */ if(p_ext_cfg->chunk_size == 0) { MSG("[%s] Chunk size is 0, truncate verify count to 1(v3)\n",MOD); p_ext_cfg->verify_count = 1; } /* remove exceed region */ for(i=p_ext_cfg->verify_count-1; i>=0; i--) { if(p_ext_cfg->verify_count == 1) { /* do not remove the only one */ break; } //region_end = p_ext_cfg->verify_offset[i] + p_ext_cfg->verify_length[i]; if(p_ext_cfg->verify_offset[i] > sec_hdr->img_len) { MSG("[%s] Remove config of offset %d (0x%x)(v3)\n",MOD, p_ext_cfg->verify_offset[i],p_ext_cfg->verify_offset[i]); p_ext_cfg->verify_count = p_ext_cfg->verify_count - 1; } else { break; } } /* adjust the last region to be aligned with image length */ i = p_ext_cfg->verify_count-1; region_end = p_ext_cfg->verify_offset[i] + p_ext_cfg->verify_length[i]; if( max_pos < region_end ) { MSG("[%s] The last region's original length is %d (0x%x)\n", MOD, p_ext_cfg->verify_length[i], p_ext_cfg->verify_length[i]); p_ext_cfg->verify_length[i] = max_pos - p_ext_cfg->verify_offset[i]; MSG("[%s] Adjust last region's original length to %d (0x%x)\n", MOD, p_ext_cfg->verify_length[i], p_ext_cfg->verify_length[i]); } /* check if need to sign for whole image */ if(p_ext_cfg->verify_count == 1 && p_ext_cfg->verify_length[0]==0 ) { MSG("[%s] The sign length is zero, and sign offset is : %d (0x%x)\n",MOD,p_ext_cfg->verify_offset[0],p_ext_cfg->verify_offset[0]); p_ext_cfg->verify_length[0] = sec_hdr->img_len - p_ext_cfg->verify_offset[0] ; MSG("[%s] Set the sign length to rest whole image length : %d (0x%x)\n",MOD,p_ext_cfg->verify_length[0],p_ext_cfg->verify_length[0]); } /* check if sign region is inside the image length */ p_ext_cfg->verify_offset[p_ext_cfg->verify_count] = max_pos; for(i=0;i<p_ext_cfg->verify_count;i++) { if(sec_hdr->img_len < p_ext_cfg->verify_length[i]) { MSG("[%s] Sign length exceeds image length(v3)\n",MOD); return -1; } if(p_ext_cfg->verify_length[i] == 0) { MSG("[%s] Sign length can't be zero(v3)\n",MOD); return -1; } region_end = p_ext_cfg->verify_offset[i] + p_ext_cfg->verify_length[i]; if(sec_hdr->img_len < region_end) { MSG("[%s] Sign region exceeds image length(v3)\n",MOD); return -1; } DBG("[%d] min_pos is %d\n", i, min_pos); DBG("p_ext_cfg->verify_offset[%d] is %d\n", i, p_ext_cfg->verify_offset[i]); DBG("[%d] region_end is %d\n", i, region_end); DBG("[%d] next region start is %d\n", i, p_ext_cfg->verify_offset[i+1]); /* check if sign region is overlay */ if((min_pos<=p_ext_cfg->verify_offset[i])&& (region_end<=p_ext_cfg->verify_offset[i+1])) { DBG("[%s] Sign region (%d->%d) ok(v3)\n",MOD, p_ext_cfg->verify_offset[i], region_end-1); } else { MSG("[%s] Sign region is overlap(v3)\n",MOD); return -1; } min_pos = region_end; } p_ext_cfg->verify_offset[p_ext_cfg->verify_count] = 0; if(p_ext_cfg->verify_count == 0) { MSG("[%s] Sign region count is zero, please check program(v3)\n",MOD); return -1; } return 0; }
unsigned int get_ext_hash_sig_struct_size(SEC_CRYPTO_HASH_TYPE hash, SEC_CRYPTO_SIGNATURE_TYPE sig) { return get_sigature_size(sig) + get_hash_size(hash) + sizeof(SEC_EXTENSTION_HASH_SIG); }
unsigned int get_ext_hash_only_struct_size(SEC_CRYPTO_HASH_TYPE hash) { return get_hash_size(hash) + sizeof(SEC_EXTENSTION_HASH_ONLY); }
static int sec_signfmt_gen_hash_by_chunk(ASF_FILE img_fd, char* part_name, uint32 img_hash_off, uint32 img_hash_len, uchar *final_hash_buf, SEC_CRYPTO_HASH_TYPE hash_type, uint32 chunk_size) { uint32 br = 0; uint32 ret = 0; uchar *chunk_buf = NULL; uchar *hash_tmp = NULL; uchar *hash_comb = NULL; uint32 seek_pos = 0; uint32 hash_size = get_hash_size(hash_type); #if DUMP_MORE_FOR_DEBUG uint32 chunk_count = ((img_hash_len-1)/chunk_size)+1; #endif uint32 read_size = 0; uint32 left_size = 0; if(!img_hash_len) { SMSG(true,"[%s] hash length is zero, no need to do hash\n",MOD); ret = -1; memset(final_hash_buf, 0x00, hash_size); goto end_error; } #if DUMP_MORE_FOR_DEBUG SMSG(sec_info.bMsg,"[%s] Hash size is %d (0x%x)\n",MOD, hash_size, hash_size); SMSG(sec_info.bMsg,"[%s] Offset is %d (0x%x)\n",MOD, img_hash_off, img_hash_off); SMSG(sec_info.bMsg,"[%s] Size is %d (0x%x)\n",MOD, img_hash_len, img_hash_len); SMSG(sec_info.bMsg,"[%s] Chunk size is %d (0x%x)\n",MOD, chunk_size, chunk_size); SMSG(sec_info.bMsg,"[%s] Chunk count is %d (0x%x)\n",MOD, chunk_count, chunk_count); #endif /* allocate hash buffer */ hash_tmp = ASF_MALLOC(hash_size); hash_comb = ASF_MALLOC(hash_size*2); memset(hash_tmp, 0x00, hash_size); memset(hash_comb, 0x00, hash_size*2); /* allocate buffer with known chunk size */ chunk_buf = ASF_MALLOC(chunk_size); /* caculate first hash */ seek_pos = img_hash_off; left_size = img_hash_len; read_size = (left_size>=chunk_size)?chunk_size:left_size; br = sec_signfmt_image_read(img_fd, part_name, seek_pos*sizeof(char), (char*)chunk_buf, read_size); if(br != read_size) { SMSG(true,"[%s] read image content fail, read offset = '0x%x'\n",MOD,seek_pos); ret = -2; goto end_error; } if( sec_hash(chunk_buf,read_size,hash_tmp,hash_size) == -1) { SMSG(true,"[%s] hash fail, offset is '0x%x'(A)\n",MOD,seek_pos); ret = -3; goto end_error; } #if DUMP_MORE_FOR_DEBUG /* ------------------------------------- */ /* dump hash value for debug */ /* ------------------------------------- */ SMSG(sec_info.bMsg,"[%s] Data value(4 bytes) ==>\n",MOD); sec_signfmt_dump_buffer(chunk_buf, 4); SMSG(sec_info.bMsg,"[%s] Hash value(single) (0x%x): \n",MOD, seek_pos); sec_signfmt_dump_buffer(hash_tmp, hash_size); #endif /* copy to compose buffer (first block) */ mcpy(hash_comb,hash_tmp,hash_size); /* move next */ seek_pos += read_size; left_size -= read_size; /* loop hash */ while(left_size) { /* load data */ read_size = (left_size>=chunk_size)?chunk_size:left_size; br = sec_signfmt_image_read(img_fd, part_name, seek_pos*sizeof(char), (char*)chunk_buf, read_size); if(br != read_size) { SMSG(true,"[%s] read image content fail, read offset = '0x%x'\n",MOD,seek_pos); ret = -4; goto end_error; } /* caculate this hash */ if( sec_hash(chunk_buf,read_size,hash_tmp,hash_size) == -1) { SMSG(true,"[%s] hash fail, offset is '0x%x'(B)\n",MOD,seek_pos); ret = -5; goto end_error; } #if DUMP_MORE_FOR_DEBUG /* ------------------------------------- */ /* dump hash value for debug */ /* ------------------------------------- */ SMSG(sec_info.bMsg,"[%s] Data value(4 bytes) ==>\n",MOD); sec_signfmt_dump_buffer(chunk_buf, 4); SMSG(sec_info.bMsg,"[%s] Hash value(single) (0x%x): \n",MOD, seek_pos); sec_signfmt_dump_buffer(hash_tmp, hash_size); #endif /* compose two hash to buffer (second block) */ mcpy(hash_comb+hash_size,hash_tmp,hash_size); /* caculate compose hash */ if( sec_hash(hash_comb,hash_size*2,hash_tmp,hash_size) == -1) { SMSG(true,"[%s] hash fail, offset is '0x%x'(C)\n",MOD,seek_pos); ret = -6; goto end_error; } #if DUMP_MORE_FOR_DEBUG /* ------------------------------------- */ /* dump hash value for debug */ /* ------------------------------------- */ SMSG(sec_info.bMsg,"[%s] Data value(4 bytes) ==>\n",MOD); sec_signfmt_dump_buffer(chunk_buf, 4); SMSG(sec_info.bMsg,"[%s] Hash value(comp) (0x%x): \n",MOD, seek_pos); sec_signfmt_dump_buffer(hash_tmp, hash_size); #endif /* save this hash to compose buffer (first block) */ mcpy(hash_comb,hash_tmp,hash_size); /* move next */ seek_pos += read_size; left_size -= read_size; } /* ------------------------------------- */ /* dump hash value for debug */ /* ------------------------------------- */ #if DUMP_MORE_FOR_DEBUG SMSG(sec_info.bMsg,"[%s] Hash value(final) (0x%x): \n",MOD, seek_pos); sec_signfmt_dump_buffer(hash_tmp, hash_size); #endif /* copy hash */ mcpy(final_hash_buf,hash_tmp,hash_size); end_error: ASF_FREE(hash_comb); ASF_FREE(chunk_buf); ASF_FREE(hash_tmp); 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; }
/************************************************************************** * FUNCTION To Get Image Hash **************************************************************************/ int sec_signfmt_calculate_image_hash_v3(char* part_name, SECURE_IMG_INFO_V3 *img_if, char *final_hash_buf, unsigned int hash_len, char *ext_buf) { unsigned int ret = SEC_OK; SEC_IMG_HEADER *img_hdr = (SEC_IMG_HEADER *)&img_if->header.v3; SEC_IMG_EXTENSTION_SET ext_set; uint32 ext_hdr_offset = 0; uint32 ext_hdr_len = 0; uchar *ext_hdr_buf = NULL; 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; } /* ======================== */ /* search for extension header */ /* ======================== */ memset(&ext_set, 0x00, sizeof(SEC_IMG_EXTENSTION_SET)); ext_hdr_offset = img_if->ext_offset + img_hdr->signature_length; ext_hdr_len = img_if->ext_len - img_hdr->signature_length; ext_hdr_buf = (uchar*)(ext_buf + ext_hdr_offset); 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(ASF_FILE_NULL, part_name, 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(true,"[%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 /* ======================== */ /* copy cal hash to extension header */ /* ======================== */ tmp_ptr = cal_hash_buf; for(i=0;i<ext_set.frag->frag_count;i++) { mcpy(ext_set.hash_only[i]->hash_data, tmp_ptr, hash_size); tmp_ptr += hash_size; } /* ======================== */ /* 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 /* ======================== */ /* generate final hash */ /* ======================== */ /* hash */ SMSG(sec_info.bMsg,"[%s] generate hash ... \n",MOD); if(SEC_OK != (ret = sec_hash(verify_data, verify_data_len, (uchar*)final_hash_buf, hash_len ))) { SMSG(true,"[%s] generate hash fail\n\n",MOD); ret = ERR_SIGN_FORMAT_GENERATE_HASH_FAIL; goto _hash_fail; } /* ================== */ /* dump hash data */ /* ================== */ SMSG(sec_info.bMsg,"[%s] dump hash data\n",MOD); dump_buf((uchar*)final_hash_buf,hash_len); SMSG(sec_info.bMsg,"[%s] generate hash pass\n\n",MOD); _hash_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: _magic_wrong_err: return ret; }
int pro_img_v3(char *hs_name, char *img_name,char *hdr_name) { uint32 br = 0; uchar *d_buf = NULL; uchar *d_buf_prt = NULL; uchar c_buf[SEC_IMG_HDR_SZ]; uchar *sig; uchar *hash; uint32 i = 0, ret = 0; SEC_IMG_HEADER *sec = NULL; SEC_EXTENTION_CFG *p_ext_cfg = (SEC_EXTENTION_CFG *)get_ext_cfg(); SEC_EXTENSTION_CRYPTO *crypto_ext = NULL; SEC_FRAGMENT_CFG *frag_ext = NULL; SEC_EXTENSTION_HASH_ONLY **hash_only_ext; SEC_EXTENSTION_END_MARK *end_ext = NULL; uint32 total_size = 0; uint32 real_chunk_size = 0; /* ------------------------------------- */ /* open hash and signature file */ /* ------------------------------------- */ FILE *hs_fd = fopen(hs_name,"wb"); if(hs_fd == 0) { MSG("[%s] %s not found\n",MOD,hs_name); goto _init_fail; } /* ------------------------------------- */ /* read image header */ /* ------------------------------------- */ FILE *hdr_fd = fopen(hdr_name,"r"); br = fread(c_buf,1,SEC_IMG_HDR_SZ,hdr_fd); /* read header */ sec = (SEC_IMG_HEADER *)c_buf; if(br == 0) { MSG("\n[%s] read '%s' image hdr fail, read bytes = '%d'\n",MOD,hdr_name,br); ret = -1; goto _hdr_fail; } /* ------------------------------------- */ /* initialize buffer */ /* ------------------------------------- */ sig = (uchar*) malloc(get_sigature_size(g_sig_type)); hash = (uchar*) malloc(get_hash_size(g_hash_type)); /* ------------------------------------- */ /* initialize extnesion header buffer */ /* ------------------------------------- */ crypto_ext = (SEC_EXTENSTION_CRYPTO *) allocate_ext_crypto(); frag_ext = (SEC_FRAGMENT_CFG *) allocate_ext_frag(); hash_only_ext = (SEC_EXTENSTION_HASH_ONLY **)malloc(p_ext_cfg->verify_count * sizeof(SEC_EXTENSTION_HASH_ONLY *)); for(i=0;i<p_ext_cfg->verify_count;i++) { hash_only_ext[i] = (SEC_EXTENSTION_HASH_ONLY *) allocate_ext_hash_only(g_hash_type); } end_ext = (SEC_EXTENSTION_END_MARK *) allocate_ext_end(); /* ------------------------------------- */ /* initial extenstion header */ /* ------------------------------------- */ crypto_ext->hash_type = g_hash_type; crypto_ext->sig_type = g_sig_type; crypto_ext->enc_type = SEC_CRYPTO_ENC_UNKNOWN; frag_ext->frag_count = p_ext_cfg->verify_count; frag_ext->chunk_size = p_ext_cfg->chunk_size; for(i=0;i<p_ext_cfg->verify_count;i++) { hash_only_ext[i]->hash_offset = p_ext_cfg->verify_offset[i]; hash_only_ext[i]->hash_len = p_ext_cfg->verify_length[i]; } /* ----------------------------------------- */ /* generate hash for each region by chunk size */ /* ----------------------------------------- */ FILE *img_fd = fopen(img_name,"r"); if(img_fd == 0) { MSG("[%s] %s not found\n",MOD,img_name); ret = -1; goto _img_open_fail; } for(i=0;i<p_ext_cfg->verify_count;i++) { if(frag_ext->chunk_size == 0) { real_chunk_size = hash_only_ext[i]->hash_len; } else { real_chunk_size = frag_ext->chunk_size; } if(gen_hash_by_chunk(img_fd, hash_only_ext[i]->hash_offset, hash_only_ext[i]->hash_len, hash, hash_only_ext[i]->sub_type, real_chunk_size)!=0) { ret = -1; goto _ext_hash_fail; } mcpy(hash_only_ext[i]->hash_data,hash,get_hash_size(g_hash_type)); } /* ------------------------------------- */ /* prepare buffer */ /* ------------------------------------- */ total_size = SEC_IMG_HDR_SZ + p_ext_cfg->verify_count*get_hash_size(g_hash_type)+ sizeof(*crypto_ext)+ sizeof(*frag_ext)+ p_ext_cfg->verify_count*get_ext_hash_only_struct_size(g_hash_type)+ sizeof(*end_ext); d_buf = (uchar*) malloc(total_size); d_buf_prt = d_buf; /* copy header */ mcpy(d_buf_prt,c_buf,SEC_IMG_HDR_SZ); d_buf_prt += SEC_IMG_HDR_SZ; /* copy hash */ for(i=0;i<p_ext_cfg->verify_count;i++) { mcpy(d_buf_prt,hash_only_ext[i]->hash_data,get_hash_size(g_hash_type)); d_buf_prt += get_hash_size(g_hash_type); } /* copy crypto extension */ mcpy(d_buf_prt,crypto_ext,sizeof(*crypto_ext)); d_buf_prt += sizeof(*crypto_ext); /* copy frag extension */ mcpy(d_buf_prt,frag_ext,sizeof(*frag_ext)); d_buf_prt += sizeof(*frag_ext); /* copy hash extension */ for(i=0;i<p_ext_cfg->verify_count;i++) { mcpy(d_buf_prt,hash_only_ext[i],get_ext_hash_only_struct_size(g_hash_type)); d_buf_prt += get_ext_hash_only_struct_size(g_hash_type); } /* copy end mark extension */ mcpy(d_buf_prt,end_ext,sizeof(*end_ext)); d_buf_prt += sizeof(*end_ext); /* ------------------------------------- */ /* generate hash */ /* ------------------------------------- */ if( cust_hash(d_buf,total_size,hash,get_hash_size(g_hash_type)) == -1) { MSG("[%s] Sign %s fail\n",MOD,img_name); ret = -1; goto _final_hash_fail; } /* ------------------------------------- */ /* generate signature */ /* ------------------------------------- */ if( cust_sign(d_buf,total_size,sig,get_sigature_size(g_sig_type)) == -1) { MSG("[%s] Sign %s fail\n",MOD,img_name); ret = -1; goto _final_sign_fail; } /* ------------------------------------- */ /* dump hash value for debug */ /* ------------------------------------- */ #if DUMP_MORE_FOR_DEBUG { unsigned loop_count = total_size/8; unsigned remain_count = total_size%8; MSG("[%s] Total verify size is : %d\n",MOD, total_size); for(i=0; i<loop_count ; i++) { DBG("[%s] Data value [%d-%d]==> (0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) \n",MOD, i*8, (i+1)*8-1, d_buf[0+i*8], d_buf[1+i*8], d_buf[2+i*8], d_buf[3+i*8], d_buf[4+i*8], d_buf[5+i*8], d_buf[6+i*8], d_buf[7+i*8]); } if(remain_count) { DBG("[%s] Data value [%d-%d]==> (",MOD,loop_count*8, loop_count*8+remain_count); for(i=0; i<remain_count ; i++) { DBG("0x%x,", d_buf[loop_count*8+i]); } DBG(") \n"); } } #endif MSG("[%s] Hash value : \n",MOD); for(i=0;i<get_hash_size(g_hash_type);i++) { MSG("0x%x,",hash[i]); } MSG("\n",MOD); /* ------------------------------------- */ /* write hash and signature */ /* ------------------------------------- */ fwrite (sig , 1 , get_sigature_size(g_sig_type), hs_fd); fwrite (hash , 1 , get_hash_size(g_hash_type) , hs_fd); /* ------------------------------------- */ /* write extension */ /* ------------------------------------- */ d_buf_prt = d_buf; d_buf_prt += SEC_IMG_HDR_SZ + p_ext_cfg->verify_count*get_hash_size(g_hash_type); fwrite (d_buf_prt , 1 , total_size-(SEC_IMG_HDR_SZ+p_ext_cfg->verify_count*get_hash_size(g_hash_type)), hs_fd); fclose (hs_fd); _final_sign_fail: _final_hash_fail: free(d_buf); _ext_hash_fail: _img_open_fail: _img_read_fail: free(end_ext); free(frag_ext); free(crypto_ext); free(hash_only_ext); free(hash); free(sig); _hdr_fail: fclose(hdr_fd); _init_fail: return ret; }
int gen_hash_by_chunk(FILE *img_fd, uint32 img_hash_off, uint32 img_hash_len, uchar *final_hash_buf, SEC_CRYPTO_HASH_TYPE hash_type, uint32 chunk_size) { uint32 br = 0; uint32 i = 0, ret = 0; uchar *chunk_buf = NULL; uchar *hash_tmp; uchar *hash_comb; uint32 seek_pos = 0; uint32 hash_size = get_hash_size(hash_type); uint32 chunk_count = ((img_hash_len-1)/chunk_size)+1; uint32 read_size = 0; uint32 left_size = 0; if(!img_hash_len) { MSG("[%s] hash length is zero, no need to do hash\n",MOD); ret = -1; memset(final_hash_buf, 0x00, hash_size); goto end_error; } #if DUMP_MORE_FOR_DEBUG DBG("[%s] Hash size is %d (0x%x)\n",MOD, hash_size, hash_size); DBG("[%s] Offset is %d (0x%x)\n",MOD, img_hash_off, img_hash_off); DBG("[%s] Size is %d (0x%x)\n",MOD, img_hash_len, img_hash_len); DBG("[%s] Chunk size is %d (0x%x)\n",MOD, chunk_size, chunk_size); DBG("[%s] Chunk count is %d (0x%x)\n",MOD, chunk_count, chunk_count); #endif /* allocate hash buffer */ hash_tmp = (uchar*) malloc(hash_size); hash_comb = (uchar*) malloc(hash_size*2); memset(hash_tmp, 0x00, hash_size); memset(hash_comb, 0x00, hash_size*2); /* allocate buffer with known chunk size */ chunk_buf = (uchar*) malloc(chunk_size); /* caculate first hash */ seek_pos = img_hash_off; left_size = img_hash_len; read_size = (left_size>=chunk_size)?chunk_size:left_size; fseek(img_fd,seek_pos*sizeof(char),SEEK_SET); br = fread(chunk_buf,1,read_size,img_fd); if(br != read_size) { MSG("[%s] read image content fail, read offset = '0x%x'\n",MOD,seek_pos); ret = -2; goto end_error; } if( cust_hash(chunk_buf,read_size,hash_tmp,hash_size) == -1) { MSG("[%s] hash fail, offset is '0x%x'(A)\n",MOD,seek_pos); ret = -3; goto end_error; } #if DUMP_MORE_FOR_DEBUG /* ------------------------------------- */ /* dump hash value for debug */ /* ------------------------------------- */ DBG("[%s] Data value(4 bytes) ==> (0x%x, 0x%x, 0x%x, 0x%x) \n",MOD, chunk_buf[0], chunk_buf[1], chunk_buf[2], chunk_buf[3]); DBG("[%s] Hash value(single) (0x%x): \n",MOD, seek_pos); for(i=0;i<hash_size;i++) { DBG("0x%x,",hash_tmp[i]); } DBG("\n",MOD); #endif /* copy to compose buffer (first block) */ mcpy(hash_comb,hash_tmp,hash_size); /* move next */ seek_pos += read_size; left_size -= read_size; /* loop hash */ while(left_size) { /* load data */ read_size = (left_size>=chunk_size)?chunk_size:left_size; fseek(img_fd,seek_pos*sizeof(char),SEEK_SET); br = fread(chunk_buf,1,read_size,img_fd); if(br != read_size) { MSG("[%s] read image content fail, read offset = '0x%x'\n",MOD,seek_pos); ret = -4; goto end_error; } /* caculate this hash */ if( cust_hash(chunk_buf,read_size,hash_tmp,hash_size) == -1) { MSG("[%s] hash fail, offset is '0x%x'(B)\n",MOD,seek_pos); ret = -5; goto end_error; } #if DUMP_MORE_FOR_DEBUG /* ------------------------------------- */ /* dump hash value for debug */ /* ------------------------------------- */ DBG("[%s] Data value(4 bytes) ==> (0x%x, 0x%x, 0x%x, 0x%x) \n",MOD, chunk_buf[0], chunk_buf[1], chunk_buf[2], chunk_buf[3]); DBG("[%s] Hash value(single) (0x%x): \n",MOD, seek_pos); for(i=0;i<hash_size;i++) { DBG("0x%x,",hash_tmp[i]); } DBG("\n",MOD); #endif /* compose two hash to buffer (second block) */ mcpy(hash_comb+hash_size,hash_tmp,hash_size); /* caculate compose hash */ if( cust_hash(hash_comb,hash_size*2,hash_tmp,hash_size) == -1) { MSG("[%s] hash fail, offset is '0x%x'(C)\n",MOD,seek_pos); ret = -6; goto end_error; } #if DUMP_MORE_FOR_DEBUG /* ------------------------------------- */ /* dump hash value for debug */ /* ------------------------------------- */ DBG("[%s] Data value(4 bytes) ==> (0x%x, 0x%x, 0x%x, 0x%x) \n",MOD, hash_comb[0], hash_comb[1], hash_comb[2], hash_comb[3]); DBG("[%s] Hash value(comp): \n",MOD); for(i=0;i<hash_size;i++) { DBG("0x%x,",hash_tmp[i]); } DBG("\n",MOD); #endif /* save this hash to compose buffer (first block) */ mcpy(hash_comb,hash_tmp,hash_size); /* move next */ seek_pos += read_size; left_size -= read_size; } /* ------------------------------------- */ /* dump hash value for debug */ /* ------------------------------------- */ #if DUMP_MORE_FOR_DEBUG DBG("[%s] Hash value(final) : \n",MOD); for(i=0;i<hash_size;i++) { DBG("0x%x,",hash_tmp[i]); } DBG("\n",MOD); #endif /* copy hash */ mcpy(final_hash_buf,hash_tmp,hash_size); end_error: free(hash_comb); free(chunk_buf); free(hash_tmp); return ret; }
int pro_img_v1_v2(char *hs_name, char *img_name,char *hdr_name) { uint32 br = 0; uchar *d_buf = NULL; uchar c_buf[SEC_IMG_HDR_SZ]; uchar *sig; uchar *hash; uint32 i = 0; SEC_IMG_HEADER *sec = NULL; /* ------------------------------------- */ /* open hash and signature file */ /* ------------------------------------- */ FILE *hs_fd = fopen(hs_name,"wb"); if(hs_fd == 0) { MSG("[%s] %s not found\n",MOD,hs_name); goto _err; } /* ------------------------------------- */ /* read image header */ /* ------------------------------------- */ FILE *hdr_fd = fopen(hdr_name,"r"); br = fread(c_buf,1,SEC_IMG_HDR_SZ,hdr_fd); /* read header */ sec = (SEC_IMG_HEADER *)c_buf; if(br == 0) { MSG("\n[%s] read '%s' image hdr fail, read bytes = '%d'\n",MOD,hdr_name,br); goto _err; } /* ------------------------------------- */ /* initialize buffer */ /* ------------------------------------- */ d_buf = (uchar*) malloc(SEC_IMG_HDR_SZ + sec->s_len*sizeof(char)); sig = (uchar*) malloc(get_sigature_size(g_sig_type)); hash = (uchar*) malloc(get_hash_size(g_hash_type)); mcpy(d_buf,c_buf,SEC_IMG_HDR_SZ); /* ------------------------------------- */ /* read image content */ /* ------------------------------------- */ FILE *img_fd = fopen(img_name,"r"); if(img_fd == 0) { MSG("[%s] %s not found\n",MOD,img_name); goto _err; } fseek(img_fd,sec->s_off*sizeof(char),SEEK_SET); br = fread(d_buf+SEC_IMG_HDR_SZ,1,sec->s_len,img_fd); if(br == 0) { MSG("\n[%s] read image content fail, read bytes = '%d'\n",MOD,br); goto _err; } /* ------------------------------------- */ /* Sign * @1 : file * @2 : file length to be signed * @3 : signature * @3 : signature length */ /* ------------------------------------- */ if( cust_sign(d_buf,SEC_IMG_HDR_SZ + sec->s_len,sig,get_sigature_size(g_sig_type)) == -1) { MSG("[%s] Sign %s fail\n",MOD,img_name); goto _err; } /* ------------------------------------- */ /* Hash * @1 : file * @2 : file length to be hashed * @3 : hash * @3 : hash length */ /* ------------------------------------- */ if( cust_hash(d_buf,SEC_IMG_HDR_SZ + sec->s_len,hash,get_hash_size(g_hash_type)) == -1) { MSG("[%s] Sign %s fail\n",MOD,img_name); goto _err; } /* ------------------------------------- */ /* dump hash value for debug */ /* ------------------------------------- */ MSG("[%s] Hash value : \n",MOD); for(i=0;i<get_hash_size(g_hash_type);i++) { MSG("0x%x,",hash[i]); } MSG("\n",MOD); /* ------------------------------------- */ /* write hash and signature */ /* ------------------------------------- */ fwrite (sig , 1 , get_sigature_size(g_sig_type), hs_fd); fwrite (hash , 1 , get_hash_size(g_hash_type) , hs_fd); fclose (hs_fd); free(d_buf); return 0; _err: free(d_buf); return -1; }