BestCrypt Container File Structure

This techical appendix document describes different versions of BestCrypt container file format.

Version 7 format

Version 7 container format is container header structure used in older (before 8.x) versions of BestCrypt. It is supported for backwards compatibility and used with KGSHA family of key generators. Container format consists of two parts: 512-byte hidden sector header followed by variable size encoded keyblock. We will specify each of those structures separately.

Header

V7 header is called a Hidden Sector and has a size of 512 bytes. Its purpose is to record container size, encryption algorithm used for encrypting container data, user-specified description and a number of service fields:

OffsetSizeDescription
03Lock flag. 0xEB if container is locked.
38Format version signature string. "LOCOS94 " is a value for version 7 format.
1121Unused, set to 0
324Container data size in 512-byte units
367Unused, set to 0
4311Disk label string. Set to "CRYPTED_DSK".
548FAT type. Platform dependant code for FAT filesystem type
6266User-specified container description string.
1282Format flags.
1302Format version.
132352Reserved space.
4844Size of the encoded keyblock.
4884Absolute offset of the encrypted container body in bytes.
4924File system id container is formatted in. Used only on Linux version.
4964Container encryption algorithm id.
5004Key generator module id.
5048Container signature when used with BestCrypt Enterprise.

KGSHA/KGSHA256 Keyblock

Keyblock contains encoded encryption key for encrypting container data. Specific encoding algorithm and data stored depends on the implementation of the key generation module. Build-in key generator used with V7 container format is KGSHA/KGSHA256. Its keyblock has a size of 1380 bytes and the following structure:

OffsetSizeDescription
08Key generator signature. "LOCOS94 " for KGSHA family.
84Keyblock format version.
124Container encryption algorithm id.
164Key generator hash algorithm id.
204Size of the keyblock.
244Size of the individual key slot.
284Total number of key slots.
324Keyblock status flags.
36100Key slot 1.
136100Key slot 2.
236100Key slot 3.
336100Key slot 4.
436100Key slot 5.
536100Key slot 6.
636100Key slot 7.
736100Key slot 8.
836512Random data pool.
134832Key block digest.

Container data encryption key is stored in key slots, each encoded by a unique user password. There are three ways to interpret each key slot depending on the key attribute flag: main key slot, hidden key slot and verification slot. All of the three occupy the same space and generic key slot structure looks like this:

OffsetSizeDescription
064Container data encryption key.
6432Container data encryption key digest.
964Key attribute.

Each key slot is initialized with random data and stored user encryption key and digest encrypted by unique user password. Key attribute value has one of the follwing bits set:

Verification data is stored once for the main container key to provide a way to verify keys recieved from BestCrypt Enterprise server. Verification slot structure differs in the first 64 bytes of the slot data and instead of the encryption key contains a block of random bytes encrypted with the container key.

Hidden part

Since each slot is initialized with random data and later stored key data and digest encrypted by a unique user password it is indistinguishable from totally random data except for the attribute bit. However since attribute bits for all key slots are set to 0x01 upon initialization and never changed for hidden key slot it is impossible to tell a hidden key slot from empty unused key slot by looking at it.

Version 7 hidden part is constructed in a very simple (and dangerous) manner. Hidden part is positioned from the end of the main part data minus its size. I.e. if main part size is 10MB and hidden part size is 1MB then it will start at the 9MB offset in main part.

Currently it is discouraged to use hidden parts in version 7 containers in favor of version 8 which is described in its own section.

Version 8 format

Version 8 container format is a container structure used in all current version of BestCrypt on all platforms. It provides such advanced features as better hidden part protection and header encryption. As all BestCrypt container formats it consists of a header and a variable-sized encoded key region called keyblock.

Header

Version 8 header has a size of 1536 bytes (or 1.5 KB) and contains basic container information and can be encrypted to make container file indistingiushable from random data. Its unencrypted structure is as follows:

OffsetSizeDescription
03Lock flag. 0xEB if container is locked.
38Format version signature string. "LOCOS94 " is a value for version 8 format.
114Container unique id for central management identification
1528Unused
4311Disk label string. Set to "BC_KeyGenID".
544Key generator module id.
584Container format version. Set to value 3 for this format
6250User-specified description string
1128Offset of the main encrypted data in bytes
1208Total size of the main encrypted data in bytes
1284Container encryption algorithm id
1324Container encryption mode id
1364Container hash algorithm id
140512Key map structure, described below
65216Initial vector generated randomly for header encryption
668358Reserved data up to 1KB boundary
1024512Random data pool

KGGHOST Keyblock

Keyblock contains encoded encryption key for encrypting container data. Specific encoding algorithm and data stored depends on the implementation of the key generation module. Build-in key generator used with V8 container format is KGGHOST

Key map structure mentioned earlier inside container header stores information about type, location and size of the encoded encryption keys in encoded keyblock except for hidden keys. Variable-sized keyblock structure that follows container header is divided into 256-byte key slots. Each slot is described in key map by the following structure:

OffsetSizeDescription
02Size of the encoded key data.
22Type of the key encoding used.
44Reserved space

This way a 512-byte key map can store information about 64 encoded key slots, 256 bytes each. Which means that V8 container format can store 16KB of encoded key data in keyblock. Actual format of storing keyblock data is as follows:

Each key slot in KGGHOST key block stores encoded key data. There are a number of different encoding algorithms based on the user authentication type. Different algorithms produce encoded data of different size which can be stored in multiple key slots. Current set of encoding algorithms include password encoding, secret sharing encoding and public key encoding.

Hidden part

Encoded key data always contains random data irrelevant of the key encoding used, for both initialized and not-initialized key slots. The only way to known if a groups of key slots encode a valid key is to look at the key map structure element indexed by key slot number. Information about hidden key position is never written to key map which means that there is no way to known if any hidden parts exist for this container and their location.

The data of the version 8 hidden part is layed out a lot more safely. When creating version 8 hidden part of the specified size BestCrypt will try to store its data inside unused file system clusters of the main part. This way BestCrypt can protect multiple hidden parts inside a single container from overlapping. Although writing to main part can still damage hidden part the possibility is much less compared to version 7 container format.