예제 #1
0
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);
}
예제 #2
0
//! 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();
}