Couple things...
* Regarding "booleans", a C compiler will usually not "pack" several variables together on its own, and the smallest variable in C has byte size. So booleans or not, the only standard way of doing this would be to use bit fields, as variables themselves can't be any smaller than a "byte". The resulting size of such a struct with bit fields may still be larger than what's strictly needed, and is often not any smaller than an 'int' - the size of which depends on the platform. It may also not be as efficient to access.
* Regarding "bytes", this has been in a recent discussion about C. Yes the C standard doesn't actually guarantee that a "byte", which is pretty much defined as the same as a "char", is 8-bit. It' just the smallest usable size in C, and by definition, sizeof(char) is 1. sizeof() gives the size in bytes. Which again are not guaranteed to be 8-bit, but are implementation-defined.
* Now there is at least one detail in C99 standards and later, that IMO can't make a byte, as defined in the C standard, anything else than 8-bit. Warning, the following ONLY applies to C99+, not earlier standard versions. The reasoning is as follows: a "byte" is the smallest size a variable can hold. With C99+, the introduction of <stdint.h> makes int8_t/uint8_t available (some of the intxx_t are optional, but I think int8_t/uint8_t is mandatory.) It follows that the smallest size, as defined as a "byte", can't be larger than an int8_t/uint8_t, which is guaranteed to be exactly 8 bits. So, only on platforms that don't support the int8_t/uint8_t types, there could be a chance that a "byte" is not 8-bit. If a platform/compiler supports them, then a "byte" can't possibly be anything else than this, as it would imply, for instance, that sizeof(int8_t) is smaller than 1, which is not possible.