Unified Key Block
Base Key, Cipher Key, HMAC Key
Any key material is converted to a base key, i.e. a hash value of the key material. The base key is then used to produce the corresponding encryption key, and the corresponding HMAC key.
The encryption key is produced as follows:
If the cipher key size is greater than the hash size, the base key is extended with zeros. If less, the base key is truncated to cipher's key size.
The HMAC key is computed by reverting the base key and inverting its bytes.
Key Block Format
Key block includes a 64-bit random salt and exactly one key record (which may, however, represent a key group).
|. . .||Key record|
Atomic Key Records
There are three types of atomic keys: password, binary key, and Yubikey.
|1||Key type (0x01)|
The 64-bit salt and the UTF-16 password (without terminating zero) are concatenated and the resulting byte string is hashed.
|1||Key type (0x05)|
The 64-bit salt and the 512-byte long binary key are concatenated and the resulting byte string is hashed.
|1||Key type (0x08)|
The 64-bit salt and the 20-byte long Yubikey response are concatenated and the resulting byte string is hashed.
Complex Key Records
There are two types of complex keys - composite key and key group.
Composite uses several atomic keys to produce the base key. In order to decrypt data the user must provide all the composite's atomic keys.
Key group also contains several simpler keys, but unlike composite key (which also may be a part of the group), the user needs to produce any of the group subkeys in order to decrypt.
|1||Key type (0x6F)|
|1||Number of keys in the composite|
|. . .||Key records|
Only atomic keys are allowed to be parts of a composite.
The base key is XOR of the composite's atomic keys, which are computed the usual way.
|1||Key type (0x05)|
|1||Number of subkeys in the group|
|. . .||Subkeys|
Every subkey record consists of a key record (which may be either an atomic key or a composite key), and an encrypted session key:
|. . .||Key record|
|n * BlockSize||Encrypted session key|
Session key is used with key group only. It is produced exactly as composite one, i.e. as a XOR of all the computed subkeys.
The same individual subkeys are also used to produce the corresponding encrypted session key.
The size of the encrypted session key field is the minimal number of cipher blocks which is greater or equal to the hash size. For example, if the hash size is 48 bytes (384 bits), and the cipher block is 32 bytes (256 bits), then the size of the key field will be 64 (2 * 32) bytes. The session key is stored in the beginning of the field, the rest (if present) is not used and must be filled with random data. After that the field is encrypted in CBC mode using the corresponding subkeys.
Key verificator is used to determine whether the user specified the correct key material. It is value is a hash value computed 257 times as follows:
The initial value V computed exactly as the corrsponding base key, i.e.
V = HASH(salt + password)
V = HASH(salt + 512-byte binary key)
V = HASH(salt + 20-byte Yubikey response)
Then 256 iterations are performed:
V = HASH( 0 + V )
V = HASH( 0 + 1 + V )
. . .
V = HASH( 0 + 1 + ... + 255 + V )
Verificator = V
The '+' sign here means byte concatenation. Values 0, 1, ..., 255 are bytes.
Constants and Structures
Key type is a byte value. Its upper 3 bits is the key level, and the lower 5 bits is the unique key ID.
Atomic keys have key level 0. Keys with key level >0 are complex ones. A complex key may include other keys as its components provided that their key levels are less than the key level of the complex key. For example, a key group (level 5) may include a composite key (level 3) but not another key group. Likewise, a composite key may not include another composite key.
0x01 - Password
0x05 - Binary key
0x08 - Yubikey
0x6F - Composite (level 3, ID 0x0F)
0xBC - Key group (level 5, ID 0x1C)
0x0001 - Can be used for container creation
0x0002 - Can be used for container modification
0x0004 - Can be used for data decryption
0x0400 - Password is accessible in the text form
0x0800 - Is a master key
Key block is usually accompanied by a component descriptor, which specifies what components should be used for key hashing (and ciphering if a session key is used).
|16||Hash function CID|
Cipher chaining mode is always ECB (and so init vector is not used).