void EncoreBootImage::prepareImageHeader(boot_image_header_t & header) { // get identifier for the first bootable section Section * firstBootSection = findFirstBootableSection(); section_id_t firstBootSectionID = 0; if (firstBootSection) { firstBootSectionID = firstBootSection->getIdentifier(); } // fill in header fields header.m_signature[0] = 'S'; header.m_signature[1] = 'T'; header.m_signature[2] = 'M'; header.m_signature[3] = 'P'; header.m_majorVersion = ROM_BOOT_IMAGE_MAJOR_VERSION; header.m_minorVersion = ROM_BOOT_IMAGE_MINOR_VERSION; header.m_flags = ENDIAN_HOST_TO_LITTLE_U16(m_headerFlags); header.m_imageBlocks = ENDIAN_HOST_TO_LITTLE_U32(getImageSize()); header.m_firstBootableSectionID = ENDIAN_HOST_TO_LITTLE_U32(firstBootSectionID); header.m_keyCount = ENDIAN_HOST_TO_LITTLE_U16((uint16_t)m_keys.size()); header.m_headerBlocks = ENDIAN_HOST_TO_LITTLE_U16((uint16_t)numberOfCipherBlocks(sizeof(header))); header.m_sectionCount = ENDIAN_HOST_TO_LITTLE_U16((uint16_t)m_sections.size()); header.m_sectionHeaderSize = ENDIAN_HOST_TO_LITTLE_U16((uint16_t)numberOfCipherBlocks(sizeof(section_header_t))); header.m_signature2[0] = 's'; header.m_signature2[1] = 'g'; header.m_signature2[2] = 't'; header.m_signature2[3] = 'l'; header.m_timestamp = ENDIAN_HOST_TO_LITTLE_U64(getTimestamp()); header.m_driveTag = m_driveTag; // Prepare version fields by converting them to the correct byte order. header.m_productVersion = m_productVersion; header.m_componentVersion = m_componentVersion; header.m_productVersion.fixByteOrder(); header.m_componentVersion.fixByteOrder(); // the fields are dependant on others header.m_keyDictionaryBlock = ENDIAN_HOST_TO_LITTLE_U16(header.m_headerBlocks + header.m_sectionCount * header.m_sectionHeaderSize); header.m_firstBootTagBlock = ENDIAN_HOST_TO_LITTLE_U32(header.m_keyDictionaryBlock + header.m_keyCount * 2); // generate random pad bytes RandomNumberGenerator rng; rng.generateBlock(header.m_padding0, sizeof(header.m_padding0)); rng.generateBlock(header.m_padding1, sizeof(header.m_padding1)); // compute SHA-1 digest over the image header uint8_t * message = reinterpret_cast<uint8_t *>(&header.m_signature); uint32_t length = static_cast<uint32_t>(sizeof(header) - sizeof(header.m_digest)); // include padding CSHA1 hash; hash.Reset(); hash.Update(message, length); hash.Final(); hash.GetHash(header.m_digest); }
//! The identifier, length, and flags fields are taken from \a section. //! //! \todo How does length get set correctly if the length is supposed to include //! this command? EncoreBootImage::TagCommand::TagCommand(const Section & section) { m_sectionIdentifier = section.getIdentifier(); m_sectionLength = section.getBlockCount(); m_sectionFlags = section.getFlags(); }