biossums


Intention

Writing a bios for a pc-compatible includes the task of embedding various
checksums. At least there is the overall bios checksum stored in the very
last byte of the program. Depending on the number and types of services the
bios provides there are others, e.g.

-- a checksum for the pci bios extensions,
-- a checksum for the plug and play bios extensions,
-- checksums for multiprocessor bios extensions.

All these checksums have one common point: using the usual assembler directives
they are hard (if not impossible) to compute at compile time. You can either
compute them by hand --- a tedious, error-prone, task, where in addition you
often have to make unreliable assumptions about the memory layout of the
entire bios. Or you patch them directly into your compiled bios-image. Apart
from computing the checksums this is what biossums does for you.



Checksums

With the exception of the overall bios checksum, in a modern pc-bios checksums
are not used to ensure data integrity. Instead they are used in conjunction
with certain signatures to securely identify the entry points or the addresses
of important data of some bios-extensions. Because these services are often
invoked from x86 protected mode the original method via interrupts is not
applicable. Scanning (even only parts) of the bios for (short) signatures and
solely relying on this is insecure though, cause the found signature might not
refer to the sought service but rather be some obscure machine code resembling
the signature by accident.

Since signatures are usually part of a larger header or table the above
mentioned problem is being circumvented by checksumming over this header and
comparing the result to a checksum stored next to the signature. In practice the
checksum is often part of the header, chosen in a way that the contents of the
header add up to zero.



Usage

biossums is very simple and straightforward. The only (and mandatory) argument
is the file-name of the bios-image. The file is being read, patched and written.
So if you want to keep your original file for reference, use biossums on a copy
of your bios-image.

For now, biossums can only rely on signatures to find the locations of the
accompanying checksums. Therefore biossums refuses to set any checksums if it
finds more than one signature of the same type.



Example output

Run upon a Bochs bios configured for 2 CPUs (ver. 1.29) biossums displays:

PCI-Bios header at: 0x9480
Current checksum:     0xA9
Calculated checksum:  0xA9  


MP header at:       0xD0F0
Current checksum:     0xC1
Calculated checksum:  0xC1  


PCMP header at:     0xD000
Current checksum:     0x65
Calculated checksum:  0x65  


Bios checksum at:   0xFFFF
Current checksum:     0x00
Calculated checksum:  0x24  Setting checksum.


If we patch in a second "_32_" signature at offset 0x9760 and reset the PCMP
checksum to 0x00 we get:

PCI-Bios header at: 0x9480
Current checksum:     0xA9
Calculated checksum:  0xA9  

PCI-Bios header at: 0x9760
Current checksum:     0x00
Calculated checksum:  0x00  Multiple PCI headers! No checksum set.


MP header at:       0xD0F0
Current checksum:     0xC1
Calculated checksum:  0xC1  


PCMP header at:     0xD000
Current checksum:     0x00
Calculated checksum:  0x65  Setting checksum.


Bios checksum at:   0xFFFF
Current checksum:     0x00
Calculated checksum:  0x01  Setting checksum.



Possible enhancements

Although biossums takes care of all checksums being used by the bios of the
Bochs project (as of version 2.02) there are more to cover, e.g. the checksums
for "Plug and Play" bios extension.

In addition it was planned to provide further information to biossums via map-/
symbol-files to verify the locations of checksums apart from scanning for
signatures. For now this seems not to be necessary; in practice no double
signatures have been observed yet.
