Exemplo n.º 1
0
/**************************************************************************
 *  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);
    }
}
Exemplo n.º 2
0
/**************************************************************************
 *  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;
    }
}
Exemplo n.º 3
0
/**************************************************************************
 *  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;
}
Exemplo n.º 4
0
/**************************************************************************
 *  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;
}
Exemplo n.º 5
0
/**************************************************************************
 *  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;
}
Exemplo n.º 6
0
/**************************************************************************
 *  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;
}
Exemplo n.º 7
0
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;
}
Exemplo n.º 8
0
/**************************************************************************
 *  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;
}