// SPDX-License-Identifier: MPL-2.0 extern "C" { #include "api.h" #include "sha3.h" } #undef str #include #include #include #include #include #include #include #include using namespace std; namespace fs=filesystem; #pragma pack(push,1) struct initfs_header { uint8_t sign[8]={'I','n','i','t','F','i','S','y'}; uint16_t bootloader_version=0x0001; uint16_t initfs_version=0x0001; uint32_t os_version=0x00000001; uint8_t installation_id[48]={0}; uint64_t initfs_size=0; uint64_t table_size=0; uint64_t files_area_size=0; uint64_t entries_width=256; uint64_t entries_count=0; uint64_t files_area_offset=0; uint64_t entropy_check1=0; uint64_t check1=0; uint8_t entry_table_hash[64]={0}; uint8_t files_area_hash[64]={0}; uint8_t installation_id_hash_hash[64]={0}; uint8_t padding[128]={0}; uint8_t header_hash[64]={0}; }; #pragma pack(pop) #pragma pack(push,1) struct file_entry { uint64_t file_offset=0; uint64_t file_size=0; uint8_t pk[64]={0}; uint8_t hash[64]={0}; char file_name[112]={0}; }; #pragma pack(pop) #pragma pack(push,1) struct signsyst_header { uint8_t sign[8]={'S','i','g','n','S','y','s','t'}; uint16_t bootloader_version=0x0001; uint16_t initfs_version=0x0001; uint32_t os_version=0x00000001; uint8_t installation_id[48]={0}; uint64_t signature_size=0; uint64_t signature_count=0; uint64_t signsyst_size=0; uint64_t signature_block_size=0; uint8_t signature_block_hash[64]; uint8_t padding[288]={0}; uint8_t header_hash[64]={0}; }; #pragma pack(pop) void secure_erase(void *address,size_t size) { explicit_bzero(address,size); } vector generate_padding(size_t x,unsigned char p) { vector result(x,0); size_t f0=0; size_t f1=1; while (f0 initfs_files_name; vector initfs_files_size; size_t total_size=0; for (auto &entry:fs::directory_iterator(folder_path)) { if (!entry.is_regular_file()) { cout<<"[InitFSGen] Error: InitFS only support files. Following entry isn't a regular file : "< entropy_id; entropy_id.resize(48); ifstream random("/dev/urandom",ios::binary); if (!random) { cout<<"[InitFSGen] Error: Can't open secure entropy source."<(entropy_id.data()),entropy_id.size()); if (random.gcount()!=entropy_id.size()) { cout<<"[InitFSGen] Error: Can't read enougth entropy for installation id."< entropy; entropy.resize(8); random.read(reinterpret_cast(entropy.data()),entropy.size()); if (random.gcount()!=entropy.size()) { cout<<"[InitFSGen] Error: Can't read enougth entropy."<(header.installation_id_hash_hash),sizeof(header.installation_id_hash_hash)); sha3(header.installation_id_hash_hash,sizeof(header.installation_id_hash_hash),header.installation_id_hash_hash,sizeof(header.installation_id_hash_hash)); vector files_area; vector files_entries_table; vector sig_list; sig_list.resize(CRYPTO_BYTES*header.entries_count); size_t cursor=0; files_area.resize(header.files_area_size); uint8_t sk[CRYPTO_SECRETKEYBYTES]={0}; for (size_t i=0;i(files_area.data()+cursor),initfs_files_size[i]); if (file.gcount()!=initfs_files_size[i]) { cout<<"[InitFSGen] Error: Couldn't read full file: "<(112)),entry.file_name); entry.file_size=initfs_files_size[i]; entry.file_offset=cursor; sha3(files_area.data()+cursor,initfs_files_size[i],entry.hash,64); if (crypto_sign_keypair(entry.pk,sk)) { cout<<"[InitFSGen] Error: can't generate keypair for file: "< entries_table; entries_table.resize(header.table_size); for (size_t i=0;i(&header),sizeof(header)); initfs_bin.write(reinterpret_cast(entries_table.data()),entries_table.size()); initfs_bin.write(reinterpret_cast(files_area.data()),files_area.size()); initfs_bin.close(); ofstream signsyst_hash("signsyst-hash.bin",ios::binary); if (!signsyst_hash) { cout<<"[InitFSGen] Error: Can't open signsyst-hash.bin."< signsysthash(64,0); sha3(&sign_header,sizeof(sign_header),signsysthash.data(),signsysthash.size()); signsyst_hash.write(reinterpret_cast(signsysthash.data()),signsysthash.size()); signsyst_hash.close(); ofstream signsyst_bin("signsyst.bin",ios::binary); if (!signsyst_bin) { cout<<"[InitFSGen] Error: Can't open signsyst.bin."<(&sign_header),sizeof(sign_header)); signsyst_bin.write(reinterpret_cast(sig_list.data()),sig_list.size()); signsyst_bin.close(); return 0; }