/**************************************************************************
 *  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;
}
Exemple #4
0
/* 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
			}
		}
	}
Exemple #5
0
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;
}
Exemple #12
0
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;
}
Exemple #13
0
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;
}
Exemple #14
0
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;

}