This techical appendix document describes different versions of BestCrypt container file 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.
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:
Offset | Size | Description |
---|---|---|
0 | 3 | Lock flag. 0xEB if container is locked. |
3 | 8 | Format version signature string. "LOCOS94 " is a value for version 7 format. |
11 | 21 | Unused, set to 0 |
32 | 4 | Container data size in 512-byte units |
36 | 7 | Unused, set to 0 |
43 | 11 | Disk label string. Set to "CRYPTED_DSK". |
54 | 8 | FAT type. Platform dependant code for FAT filesystem type |
62 | 66 | User-specified container description string. |
128 | 2 | Format flags. |
130 | 2 | Format version. |
132 | 352 | Reserved space. |
484 | 4 | Size of the encoded keyblock. |
488 | 4 | Absolute offset of the encrypted container body in bytes. |
492 | 4 | File system id container is formatted in. Used only on Linux version. |
496 | 4 | Container encryption algorithm id. |
500 | 4 | Key generator module id. |
504 | 8 | Container signature when used with BestCrypt Enterprise. |
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:
Offset | Size | Description |
---|---|---|
0 | 8 | Key generator signature. "LOCOS94 " for KGSHA family. |
8 | 4 | Keyblock format version. |
12 | 4 | Container encryption algorithm id. |
16 | 4 | Key generator hash algorithm id. |
20 | 4 | Size of the keyblock. |
24 | 4 | Size of the individual key slot. |
28 | 4 | Total number of key slots. |
32 | 4 | Keyblock status flags. |
36 | 100 | Key slot 1. |
136 | 100 | Key slot 2. |
236 | 100 | Key slot 3. |
336 | 100 | Key slot 4. |
436 | 100 | Key slot 5. |
536 | 100 | Key slot 6. |
636 | 100 | Key slot 7. |
736 | 100 | Key slot 8. |
836 | 512 | Random data pool. |
1348 | 32 | Key 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:
Offset | Size | Description |
---|---|---|
0 | 64 | Container data encryption key. |
64 | 32 | Container data encryption key digest. |
96 | 4 | Key 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.
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 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.
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:
Offset | Size | Description |
---|---|---|
0 | 3 | Lock flag. 0xEB if container is locked. |
3 | 8 | Format version signature string. "LOCOS94 " is a value for version 8 format. |
11 | 4 | Container unique id for central management identification |
15 | 28 | Unused |
43 | 11 | Disk label string. Set to "BC_KeyGenID". |
54 | 4 | Key generator module id. |
58 | 4 | Container format version. Set to value 3 for this format |
62 | 50 | User-specified description string |
112 | 8 | Offset of the main encrypted data in bytes |
120 | 8 | Total size of the main encrypted data in bytes |
128 | 4 | Container encryption algorithm id |
132 | 4 | Container encryption mode id |
136 | 4 | Container hash algorithm id |
140 | 512 | Key map structure, described below |
652 | 16 | Initial vector generated randomly for header encryption |
668 | 358 | Reserved data up to 1KB boundary |
1024 | 512 | Random data pool |
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:
Offset | Size | Description |
---|---|---|
0 | 2 | Size of the encoded key data. |
2 | 2 | Type of the key encoding used. |
4 | 4 | Reserved 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.
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.