diff options
author | Nicolas Dechesne <nicolas.dechesne@linaro.org> | 2018-05-29 09:36:27 +0200 |
---|---|---|
committer | Nicolas Dechesne <nicolas.dechesne@linaro.org> | 2018-05-29 09:36:27 +0200 |
commit | d113efa107ccc01928e89cdeae9f9e96e2824daf (patch) | |
tree | c08b66cb1bd82f1b9823ca5ec68bd621fa93d016 | |
parent | 46039882ec75dc57e3d11d523f8287683c8cc70c (diff) |
signer: fix indentation and style
Signed-off-by: Nicolas Dechesne <nicolas.dechesne@linaro.org>
-rw-r--r-- | signer/signlk.cpp | 452 |
1 files changed, 214 insertions, 238 deletions
diff --git a/signer/signlk.cpp b/signer/signlk.cpp index e130758..73e77c2 100644 --- a/signer/signlk.cpp +++ b/signer/signlk.cpp @@ -26,17 +26,10 @@ /* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN */ /* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /******************************************************************************/ - - #include <iostream> #include "elfio/elfio.hpp" using namespace ELFIO; - - -/*---------------------------------------------------------------------------- - * Definitions and macros - *-------------------------------------------------------------------------*/ #define HASH_CODE_SIZE 0x80 #define SIGNATURE_SIZE 0x100 #define CERT_CHAIN_SIZE 0x1800 @@ -48,243 +41,226 @@ using namespace ELFIO; #define MI_PBT_FLAG_SEGMENT_TYPE_MASK 0x7000000 #define MI_PBT_FLAG_SEGMENT_TYPE_SHIFT 0x18 -/*---------------------------------------------------------------------------- - * Type declerations - *-------------------------------------------------------------------------*/ - -typedef unsigned char uint8; -typedef unsigned int uint32 ; -typedef unsigned long long uint64 ; - - -/* struct to store hash segment header */ +// struct to store hash segment header typedef struct { - unsigned int header_vsn_num; /* Header version number. */ - unsigned int image_id; /* Identifies the type of image this header represents . */ - unsigned int image_src; /* Location of image in flash. */ - unsigned int image_dest_ptr; /* Pointer to location to store image in RAM.*/ - unsigned int image_size; /* Size of complete image in bytes */ - unsigned int code_size; /* Size of code region of image in bytes */ - unsigned int signature_ptr; /* Pointer to images attestation signature */ - unsigned int signature_size; /* Size of the attestation signature in bytes */ - unsigned int cert_chain_ptr; /* Pointer to the certificates associated with the image. */ - unsigned int cert_chain_size; /* Size of the attestation chain in bytes */ - + unsigned header_vsn_num; // Header version number + unsigned image_id; // Identifies the type of image this header represents + unsigned image_src; // Location of image in flash + unsigned image_dest_ptr; // Pointer to location to store image in RAM + unsigned image_size; // Size of complete image in bytes + unsigned code_size; // Size of code region of image in bytes + unsigned signature_ptr; // Pointer to images attestation signature + unsigned signature_size; // Size of the attestation signature in bytes + unsigned cert_chain_ptr; // Pointer to the certificates associated with the image + unsigned cert_chain_size; // Size of the attestation chain in bytes } mi_boot_image_header_type; - /*---------------------------------------------------------------------------- - * Static helper functions - *-------------------------------------------------------------------------*/ - -/* This function writes data to file */ -static uint32 saveDataToFile(std::string file_name, const char *data, uint32 len) +static int saveDataToFile(std::string file_name, const char *data, unsigned len) { - std::ofstream ostreamfile; - ostreamfile.open( file_name, std::ios::out | std::ios::binary ); - if ( !ostreamfile ) { - std::cout << "cant open data To Sig file"<< file_name << std::endl; - return 1; - } - ostreamfile.write(data,len); - ostreamfile.close(); - return 0; + std::ofstream ostreamfile; + ostreamfile.open(file_name, std::ios::out | std::ios::binary); + if (!ostreamfile) { + std::cout << "cant open data To Sig file" << file_name << std::endl; + return 1; + } + ostreamfile.write(data,len); + ostreamfile.close(); + return 0; } - - - /*---------------------------------------------------------------------------- - * Main functions - *-------------------------------------------------------------------------*/ - -int main( int argc, char** argv ) +int main(int argc, char** argv) { - if ( argc != 4 ) { - std::cout << "Usage: signlk <unsigned_elf_file> <signed_elf_file> <tmp_dir>"<< std::endl; - return 1; - } - - /* Create an elfio reader and writer */ - elfio reader; - elfio writer; - std::ifstream stream; - std::ofstream ostreamfile; - char cert_chain[MAX_CERT_CHAIN_SIZE]={0}; - unsigned int hash_segment_address = 0; - std::string tmp_path=(std::string)(argv[3]); - mi_boot_image_header_type mi={0}; - section* data_sec = NULL; - section* mi_sec = NULL; - segment* header_seg = NULL; - segment* hash_seg = NULL; - segment* orig_hash_seg = NULL; - Elf_Xword wflags =0; - Elf_Word maxAddress = 0; - segment* max_seg = NULL; - uint32 hash_offset = 2; - char elfHeader[0x1000]; - Elf_Half seg_num=0; - char Si[8] ={0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x3F}; - char So[8] ={0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C}; - - /* Load ELF data */ - if ( !reader.load( argv[1] ) ) { - std::cout << "Can't find or process ELF file " << argv[1] << std::endl; - return 2; - } - - /* create a write configuration */ - writer.create( reader.get_class(), reader.get_encoding() ); - writer.set_os_abi( reader.get_os_abi() ); - writer.set_type( reader.get_type() ); - writer.set_machine( reader.get_machine() ); - writer.set_flags(reader.get_flags()); - - seg_num = reader.segments.size(); - - /* Create hash data section*/ - header_seg = writer.segments.add(); - hash_seg = writer.segments.add(); - - /* Init the certificates chain file */ - for ( int i = 0; i < MAX_CERT_CHAIN_SIZE; ++i ) cert_chain[i]=0xff; - - /* Find the hash segment in the input file */ - for ( int i = 0; i < seg_num; ++i ) { - segment* pseg = reader.segments[i]; - wflags = pseg->get_flags() ; - if (((wflags&MI_PBT_FLAG_SEGMENT_TYPE_MASK)>>MI_PBT_FLAG_SEGMENT_TYPE_SHIFT) == 0x2){ - orig_hash_seg = pseg; - hash_segment_address = pseg->get_virtual_address(); - hash_offset = 0; - break; - } - if (pseg->get_physical_address() > maxAddress) - { - maxAddress = pseg->get_physical_address(); - max_seg = pseg; - } - } - - /* Fill hash segment with empty section */ - hash_seg->set_type( PT_NULL); - hash_seg->set_virtual_address( hash_segment_address ); - hash_seg->set_physical_address( hash_segment_address); - hash_seg->set_flags( HASH_SE_FLAG ); - hash_seg->set_align( HASH_SE_ALIGN ); - hash_seg->set_file_size(mi.image_size); - hash_seg->set_memory_size(MAX_CERT_CHAIN_SIZE); - mi_sec = writer.sections.add( ".mi" ); - mi_sec->set_type( PT_LOPROC ); - mi_sec->set_flags( SHF_ALLOC ); - mi_sec->set_addr_align( HASH_SE_ALIGN ); - /* Create a hash segment if needed */ - if (orig_hash_seg == NULL){ - hash_segment_address = (maxAddress + max_seg->get_memory_size()); - hash_segment_address += HASH_SE_ALIGN - (hash_segment_address % HASH_SE_ALIGN); - } - - /* set the hash segment header data */ - mi.image_id = 0x3; - mi.image_dest_ptr = hash_segment_address + sizeof(mi_boot_image_header_type); - mi.code_size = HASH_CODE_SIZE; - mi.header_vsn_num = 0; - mi.signature_ptr = mi.image_dest_ptr + mi.code_size; - mi.signature_size =SIGNATURE_SIZE; - mi.cert_chain_ptr = mi.signature_ptr + mi.signature_size; - mi.cert_chain_size = CERT_CHAIN_SIZE; - mi.image_size = mi.cert_chain_size + mi.signature_size + mi.code_size; - memcpy(cert_chain,&mi,sizeof(mi)); - mi_sec->set_data(cert_chain,MAX_CERT_CHAIN_SIZE); - /* Add code section into program segment */ - hash_seg->add_section_index( mi_sec->get_index(), mi_sec->get_addr_align() ); - - /* copy the original elf segments to the signed elf */ - for ( int i = 0; i < seg_num; ++i ) { - segment* pseg = reader.segments[i]; - wflags = pseg->get_flags() ; - if (wflags & HASH_SE_FLAG) continue; - segment* data_seg = writer.segments.add(); - - data_seg->set_type( pseg->get_type() ); - data_seg->set_virtual_address( pseg->get_virtual_address() ); - data_seg->set_physical_address( pseg->get_physical_address() ); - data_seg->set_flags( pseg->get_flags() ); - data_seg->set_align( pseg->get_align() ); - data_seg->set_file_size(pseg->get_file_size()); - data_seg->set_memory_size(pseg->get_memory_size()); - - data_sec = writer.sections.add( "" ); - data_sec->set_type( SHT_PROGBITS ); - data_sec->set_flags( SHF_ALLOC ); - data_sec->set_addr_align( 1 ); - data_sec->set_data( pseg->get_data(), pseg->get_file_size() ); - data_seg->add_section_index( data_sec->get_index(), data_sec->get_addr_align() ); - - /* export each segment */ - const char * data=pseg->get_data(); - if (data != NULL) - { - std::string tmpFileName = tmp_path+"/segment"; - char index = i+hash_offset+'0'; - tmpFileName.append(&index,1); - saveDataToFile(tmpFileName, pseg->get_data(), pseg->get_file_size()); - } - } - - Elf_Half headerSize = writer.get_header_size() + writer.segments.size() * writer.get_segment_entry_size(); - /* Create data section */ - data_sec = writer.sections.add( "" ); - data_sec->set_type( SHT_NOBITS ); - data_sec->set_flags( SHF_ALLOC ); - data_sec->set_addr_align( 1 ); - char data[0x100]={0}; - data_sec->set_data( data, headerSize ); - - /* Create a read/write segment */ - header_seg->set_type( PT_NULL ); - header_seg->set_virtual_address( 0 ); - header_seg->set_physical_address( 0 ); - header_seg->set_flags( 0 ); - header_seg->set_align( 4 ); - - /* Add code section into program segment */ - header_seg->add_section_index( data_sec->get_index(), data_sec->get_addr_align() ); - - /* set the entry point */ - writer.set_entry(reader.get_entry()); - - /* Create ELF file */ - writer.save(argv[2]); - - /* Read ELF file header */ - stream.open( argv[2], std::ios::in | std::ios::binary ); - if ( !stream ) { - std::cout << "cant open tmp file" << std::endl; - return 1; - } - - stream.seekg( 0 ); - stream.read(elfHeader,headerSize); - stream.close(); - - /* export data to files */ - std::string tmpheaderFileName = tmp_path+"/header"; - saveDataToFile(tmpheaderFileName, elfHeader, headerSize); - std::string tmphashFileName = tmp_path+"/hash"; - char empty[0x20]; - saveDataToFile(tmphashFileName, empty, 0x20); - std::string tmphashSegrFileName = tmp_path+"/hashSeg"; - saveDataToFile(tmphashSegrFileName, cert_chain, MAX_CERT_CHAIN_SIZE); - - std::string tmpSiFileName = tmp_path+"/Si"; - saveDataToFile(tmpSiFileName, Si, sizeof(Si)); - std::string tmpSoFileName = tmp_path+"/So"; - saveDataToFile(tmpSoFileName, So, sizeof(So)); - - std::string sectionSize = std::to_string(writer.get_section_entry_size()); - std::string tmpSectionSizeFileName = tmp_path+"/sectionSize"; - saveDataToFile(tmpSectionSizeFileName, sectionSize.c_str(), sizeof(sectionSize.c_str())); - - return 0; + if (argc != 4) { + std::cout << "Usage: signlk <unsigned_elf_file> <signed_elf_file> <tmp_dir>" << std::endl; + return 1; + } + + // Create an elfio reader and writer + elfio reader; + elfio writer; + std::ifstream stream; + std::ofstream ostreamfile; + char cert_chain[MAX_CERT_CHAIN_SIZE] = {0}; + unsigned hash_segment_address = 0; + std::string tmp_path = (std::string)(argv[3]); + mi_boot_image_header_type mi = {0}; + section* data_sec = NULL; + section* mi_sec = NULL; + segment* header_seg = NULL; + segment* hash_seg = NULL; + segment* orig_hash_seg = NULL; + Elf_Xword wflags = 0; + Elf_Word maxAddress = 0; + segment* max_seg = NULL; + unsigned hash_offset = 2; + char elfHeader[0x1000]; + Elf_Half seg_num = 0; + char Si[8] = {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x3F}; + char So[8] = {0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C}; + + // Load ELF data + if (!reader.load(argv[1])) { + std::cout << "Can't find or process ELF file " << argv[1] << std::endl; + return 2; + } + + // create a write configuration + writer.create(reader.get_class(), reader.get_encoding()); + writer.set_os_abi(reader.get_os_abi()); + writer.set_type(reader.get_type()); + writer.set_machine(reader.get_machine()); + writer.set_flags(reader.get_flags()); + + seg_num = reader.segments.size(); + + // Create hash data section + header_seg = writer.segments.add(); + hash_seg = writer.segments.add(); + + // Init the certificates chain file + for (int i = 0; i < MAX_CERT_CHAIN_SIZE; ++i) + cert_chain[i]=0xff; + + // Find the hash segment in the input file + for (int i = 0; i < seg_num; ++i) { + segment* pseg = reader.segments[i]; + wflags = pseg->get_flags() ; + if (((wflags&MI_PBT_FLAG_SEGMENT_TYPE_MASK)>>MI_PBT_FLAG_SEGMENT_TYPE_SHIFT) == 0x2){ + orig_hash_seg = pseg; + hash_segment_address = pseg->get_virtual_address(); + hash_offset = 0; + break; + } + if (pseg->get_physical_address() > maxAddress) { + maxAddress = pseg->get_physical_address(); + max_seg = pseg; + } + } + + // Fill hash segment with empty section + hash_seg->set_type(PT_NULL); + hash_seg->set_virtual_address(hash_segment_address); + hash_seg->set_physical_address(hash_segment_address); + hash_seg->set_flags(HASH_SE_FLAG); + hash_seg->set_align(HASH_SE_ALIGN); + hash_seg->set_file_size(mi.image_size); + hash_seg->set_memory_size(MAX_CERT_CHAIN_SIZE); + mi_sec = writer.sections.add(".mi"); + mi_sec->set_type(PT_LOPROC); + mi_sec->set_flags(SHF_ALLOC); + mi_sec->set_addr_align(HASH_SE_ALIGN); + + // Create a hash segment if needed + if (orig_hash_seg == NULL){ + hash_segment_address = maxAddress + max_seg->get_memory_size(); + hash_segment_address += HASH_SE_ALIGN - (hash_segment_address % HASH_SE_ALIGN); + } + + // set the hash segment header data + mi.image_id = 0x3; + mi.image_dest_ptr = hash_segment_address + sizeof(mi_boot_image_header_type); + mi.code_size = HASH_CODE_SIZE; + mi.header_vsn_num = 0; + mi.signature_ptr = mi.image_dest_ptr + mi.code_size; + mi.signature_size =SIGNATURE_SIZE; + mi.cert_chain_ptr = mi.signature_ptr + mi.signature_size; + mi.cert_chain_size = CERT_CHAIN_SIZE; + mi.image_size = mi.cert_chain_size + mi.signature_size + mi.code_size; + memcpy(cert_chain, &mi, sizeof(mi)); + mi_sec->set_data(cert_chain, MAX_CERT_CHAIN_SIZE); + + // Add code section into program segment + hash_seg->add_section_index(mi_sec->get_index(), mi_sec->get_addr_align()); + + // copy the original elf segments to the signed elf + for (int i = 0; i < seg_num; ++i) { + segment* pseg = reader.segments[i]; + wflags = pseg->get_flags() ; + if (wflags & HASH_SE_FLAG) continue; + + segment* data_seg = writer.segments.add(); + + data_seg->set_type(pseg->get_type()); + data_seg->set_virtual_address(pseg->get_virtual_address()); + data_seg->set_physical_address(pseg->get_physical_address()); + data_seg->set_flags(pseg->get_flags()); + data_seg->set_align(pseg->get_align()); + data_seg->set_file_size(pseg->get_file_size()); + data_seg->set_memory_size(pseg->get_memory_size()); + + data_sec = writer.sections.add(""); + data_sec->set_type(SHT_PROGBITS); + data_sec->set_flags(SHF_ALLOC); + data_sec->set_addr_align(1); + data_sec->set_data(pseg->get_data(), pseg->get_file_size()); + data_seg->add_section_index(data_sec->get_index(), data_sec->get_addr_align()); + + // export each segment + const char * data=pseg->get_data(); + if (data != NULL) { + std::string tmpFileName = tmp_path + "/segment"; + char index = i + hash_offset + '0'; + tmpFileName.append(&index,1); + saveDataToFile(tmpFileName, pseg->get_data(), pseg->get_file_size()); + } + } + + Elf_Half headerSize = writer.get_header_size() + writer.segments.size() * writer.get_segment_entry_size(); + + // Create data section + data_sec = writer.sections.add(""); + data_sec->set_type(SHT_NOBITS); + data_sec->set_flags(SHF_ALLOC); + data_sec->set_addr_align(1); + char data[0x100]={0}; + data_sec->set_data(data, headerSize); + + // Create a read/write segment + header_seg->set_type(PT_NULL); + header_seg->set_virtual_address(0); + header_seg->set_physical_address(0); + header_seg->set_flags(0); + header_seg->set_align(4); + + // Add code section into program segment + header_seg->add_section_index(data_sec->get_index(), data_sec->get_addr_align()); + + // Finalize ELF file + writer.set_entry(reader.get_entry()); + writer.save(argv[2]); + + // Read back ELF file header + stream.open(argv[2], std::ios::in | std::ios::binary); + if (!stream) { + std::cout << "cant open tmp file" << std::endl; + return 1; + } + + stream.seekg(0); + stream.read(elfHeader, headerSize); + stream.close(); + + // export data to files + std::string tmpheaderFileName = tmp_path + "/header"; + saveDataToFile(tmpheaderFileName, elfHeader, headerSize); + + std::string tmphashFileName = tmp_path + "/hash"; + char empty[0x20]; + saveDataToFile(tmphashFileName, empty, 0x20); + + std::string tmphashSegrFileName = tmp_path + "/hashSeg"; + saveDataToFile(tmphashSegrFileName, cert_chain, MAX_CERT_CHAIN_SIZE); + + std::string tmpSiFileName = tmp_path + "/Si"; + saveDataToFile(tmpSiFileName, Si, sizeof(Si)); + + std::string tmpSoFileName = tmp_path + "/So"; + saveDataToFile(tmpSoFileName, So, sizeof(So)); + + std::string sectionSize = std::to_string(writer.get_section_entry_size()); + std::string tmpSectionSizeFileName = tmp_path + "/sectionSize"; + saveDataToFile(tmpSectionSizeFileName, sectionSize.c_str(), sizeof(sectionSize.c_str())); + + return 0; } |