92 lines
6.1 KiB
Markdown
92 lines
6.1 KiB
Markdown
# Custom filesystems
|
|
|
|
## Introduction
|
|
|
|
Vystem define two new filesystems: InitFS and SignSyst. The purpose of these filesystems are to store any sensitive systems files. Both of these filesystems are designed to be integrated together. For each InitFS, there is always a SignSyst and vice versa. These filesystems are generated by the `initfsgen` utility. In this file, we describe how they are structured, not how they are generated, verified or used. Please take note that these filesystems has been designed for the x86-64 architecture and for little endian usage.
|
|
|
|
## InitFS
|
|
|
|
InitFS is new, very simple filesystem. It doesn't support folders and is completely immutable after generation. It has been designed to support strong files integrity check and be loader as one big chunk into memory.
|
|
|
|
### Header
|
|
|
|
The header of any InitFS filesystem is as follow:
|
|
- Signature: 8 bytes that are set to `InitFiSy` in ASCII
|
|
- Bootloader version: an uint16_t indicating the bootloader version, currently set to `0x0001`
|
|
- InitFS version: an uint16_t indicating the InitFS version, currently set to `0x0001`
|
|
- OS version: an uint32_t indicating the OS version, currently set to `0x00000001`
|
|
- Installation ID: an array of 48 completely random bytes. His SHA3-512 hash is stored inside the `initfs-footprint.bin` file, protected by SPFIE
|
|
- InitFS Size: the amount of bytes in the total filesystem, not forcefully rounded to the disk block size. Stored as an uint64_t
|
|
- Files table size: the amount of bytes used for the filesystem files table. Stored as an uint64_t
|
|
- Files content size: the amount of bytes for the filesystem files content area. Stored as an uint64_t
|
|
- Entry width: the width of a file table entry. In the current version of InitFS, must always be set to 256. Stored as an uint64_t
|
|
- Entries count: the count of entries inside files table, stored as an uint64_t
|
|
- Files content area offset: the amount to bytes to add to the filesystem base to reach the files content area. Stored as an uint64_t
|
|
- Entropy: 8 bytes of random data, stored as an uint64_t
|
|
- Entropy check: 8 bytes of a value generated with this formula : `header.entropy_check=(header.entropy*0x9E3779B185EBCA87)^header.entropy`. Stored as an uint64_t
|
|
- Files table hash: an array of 64 bytes containing the SHA3-512 hash of the files table
|
|
- Files content area hash: an array of 64 bytes containig the SHA3-512 hash of the files content area
|
|
- Installation ID double hash: an array of 64 bytes containing the SHA3-512 hash of the content of the `initfs-footprint.bin` file.
|
|
- Padding: 128 bytes of padding generated with a specific pattern (see below)
|
|
- Header hash: an array of 64 bytes containing the SHA3-512 of the InitFS header, not including the last 64 bytes
|
|
|
|
This header is exactly 512 bytes. The mecanism decribed above with the installation ID and the `initfs-footprint.bin` is to ensure that an installation of Blastproof find his associated InitFS.
|
|
|
|
### Files table and files entries
|
|
|
|
The files table is filled with files entries structured as follow, each being 256 bytes:
|
|
- File offset in the files content area, starting at the beginning of the files content area,stored as an uint64_t
|
|
- File size, stored in bytes as an uint64_t
|
|
- Sphincs+ public key of the file, stored as an array of 64 bytes
|
|
- SHA3-512 hash of the file, stored as an array of 64 bytes
|
|
- File name, stored as an array of 112 bytes
|
|
|
|
Files names can only use ASCII and have to be finished by `\0`, unless the file name is exactly 112 characters.
|
|
|
|
### Files content area
|
|
|
|
The files content area come just after the files table and contain the files content.
|
|
|
|
## SignSyst
|
|
|
|
SignSyst is a special filesystem: it doesn't contain files but signatures. Signatures have all the same fixed size and are stored in the same order as the files entries inside the associated InitFS.
|
|
|
|
### Header
|
|
|
|
The header of any SignSyst is as follow:
|
|
- Signature: 8 bytes that are set to `SignSyst` in ASCII
|
|
- Bootloader version: an uint16_t indicating the bootloader version, need to be set as same as the associated InitFS
|
|
- InitFS version: an uint16_t indicating the InitFS version, need to be set as same as the associated InitFS
|
|
- OS version: an uint32_t indicating the OS version, need to be set as same as the associated InitFS
|
|
- Installation ID: an array of 48 bytes containing the installation ID, need to be set as same as the associated InitFS
|
|
- Signature size: the size of a signature, stored as an uint64_t
|
|
- Signature count: the count of signatures, stored as an uint64_t
|
|
- SignSyst size: the amount of bytes in the total filesystem, not forcefully rounded to the disk block size. Stored as an uint64_t
|
|
- Signature area size: the amount of bytes used to actually store the signatures, stored as an uint64_t
|
|
- Signature area hash: an array of 64 bytes containing the SHA3-512 hash of the signatures area
|
|
- Padding: 288 bytes of padding generated with the same pattern as InitFS
|
|
- Header hash: an array of 64 bytes containing the SHA3-512 of the SignSyst header, not including the last 64 bytes
|
|
|
|
The header is exactly 512 bytes. The file `signsyst-hash.bin`, protected by SPFIE, contain the full hash of the SignSyst header.
|
|
|
|
### Signatues area
|
|
|
|
The signatures area come just after the SignSyst header and contain all Sphincs+ signatures.
|
|
|
|
## Padding generation
|
|
|
|
InitFS and SignSyst padding use a very specific generation method:
|
|
The padding is first initialized with zeroed bytes, after which a marker value `p` is written at positions determined by the sequence defined by (f0,f1)=(0,1) and iteratively updated as (f0←f1,f1←f0+f1). At each step, the byte at index `f0` is set to `p`, resulting in writes at offsets following the Fibonacci sequence until the index exceeds the padding size.
|
|
In InitFS, the marquer value `p` is the first byte of the installation ID.
|
|
In SignSyst, the marquer value `p` is the last byte of the installation ID.
|
|
|
|
## Hash generation
|
|
|
|
The files table hash, files content area hash and signatures area hash are altered in a certain way: their 48 last bytes are xored with the installation ID. The header hash for both filesystems are generated at the final end of the generation process.
|
|
|
|
## Stored files
|
|
|
|
To this day, the InitFS contain the following files
|
|
- `shelter.vyx`
|
|
- `keycard.bin`
|