SEC_EXTENSTION_HASH_ONLY* allocate_ext_hash_only(SEC_CRYPTO_HASH_TYPE hash) { SEC_EXTENSTION_HASH_ONLY *ext; unsigned int total_size = get_ext_hash_only_struct_size(hash); ext = (SEC_EXTENSTION_HASH_ONLY *)malloc(total_size); memset(ext, 0, total_size); ext->magic = SEC_EXTENSION_HEADER_MAGIC; ext->ext_type = SEC_EXT_HDR_HASH_ONLY; ext->sub_type = hash; ext->hash_offset = 0; ext->hash_len = 0; return ext; }
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; }