This technical appendix document describes two different versions of BestCrypt container file formats.
The Version 7 (V7) container format is the container header structure used in older (pre-8.x) versions of BestCrypt. It is supported for backwards compatibility and used with the KGSHA family of key generators. This container format consists of two parts: a 512-byte hidden sector header and avariable size encoded keyblock that follows. The following sections describe each of these structures separately.
The 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 the following 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-dependent code for FAT file system type |
62 | 66 | User-specified container description string. |
128 | 2 | Format flags |
130 | 2 | Format version |
132 | 352 | Reserved space |
484 | 4 | Size of encoded keyblock |
488 | 4 | Absolute offset of the encrypted container body in bytes |
492 | 4 | File system in which the ID container is formatted; 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. The specific encoding algorithm and data stored depends on the implementation of the key generation module. The built-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 keyblock |
24 | 4 | Size of individual key slot |
28 | 4 | Total number of key slot. |
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 keys are 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 three of these occupy the same space and the 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 a unique user password. Key attribute values have one of the following 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; instead of the encryption key, it contains a block of random bytes encrypted with the container key.
Because 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, because attribute bits for all key slots are set to 0x01 upon initialization and never changed for the hidden key slot, it is impossible to tell a hidden key slot from an empty, unused key slot just by looking at it.
Version 7 hidden parts are constructed in a very simple (and dangerous) manner. The hidden part is positioned from the end of the main part data minus its size. For instance, if the main part size is 10MB and the hidden part size is 1MB, then it will start at the 9MB offset in the main part.
Currently it is discouraged to use hidden parts in version 7 containers in favor of version 8, which is described in the next section.
The 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. Like all BestCrypt container formats, it consists of a header and a variable-sized encoded key region called keyblock.
A Version 8 header has a size of 1536 bytes (or 1.5 KB), contains basic container information and can be encrypted to make a 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 |
A keyblock contains an encoded encryption key for encrypting container data. The specific encoding algorithm and data stored depends on the implementation of the key generation module. The built-in key generator used with the V8 container format is KGGHOST.
The aforementioned key map structure inside the container header stores information about the type, location and size of the encoded encryption keys in an encoded keyblock, except for hidden keys. A variable-sized keyblock structure that follows container header is divided into 256-byte key slots. Each slot is described in the key map using the following structure:
Offset | Size | Description |
---|---|---|
0 | 2 | Size of the encoded key data |
2 | 2 | Type of 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. The actual format of storing keyblock data is as follows:
Each key slot in a KGGHOST keyblock 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 sizes, which can be stored in multiple key slots. The current set of encoding algorithms includes password encoding, secret sharing encoding and public key encoding.
Encoded key data always contains random data regardless of the key encoding used, for both initialized and not-initialized key slots. The only way to know if a group 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 the key map, which means that there is no way to know if any hidden parts exist for a particular container and its location.
The data of the version 8 hidden part is layed out much more safely than that of the version 7. When creating a version 8 hidden part of a specified size, BestCrypt will try to store its data inside unused file system clusters of the main part. This way, BestCrypt can prevent multiple hidden parts inside a single container from overlapping. Although writing to the main part can still damage a hidden part, the possibility is much lower as compared to the version 7 container format.