# Vystem FAT Trusted Manifest

## Introduction

Vystem FAT Trusted Manifest (VFTM) is a structure that can be found in the reserved sectors of any FAT32 filesystem generated by VyBuild (please see the conditions for VyBuild to generate this manifest in the VyBuild documentation). It's the first layer of defense in the Vystem Secure Boot Chain, being verified independantly at each boot.

## Position and structure

VTFM can be divided into three parts:
- the VFTM manifest itself, containing all importants informations and hashs. It's stored somewhere between the sector 8 and 31 of the FAT32 filesystem
- the manifest public key. It's stored somewhere between the sector 8 and 31 of the FAT32 filesystem, but never on the same sector of the manifest itself
- the manifest signature. It's stored after the FAT32 filesystem, just before the end of the ESP partition

The manifest and manifest public key have their position determined by this function:
``` C
void generate_vftm_sectors(const uint8_t* part_guid,int* sector_manifest,int* sector_public_key) {
  uint32_t h=0x811c9dc5;
  for (int i=0;i<16;i++) h=(h^part_guid[i])*0x01000193;
  *sector_manifest=8+(h%24);
  *sector_public_key=8+(((h>>16)%23+(*sector_manifest-7))%24);
}
```

The `part_guid` argument is an array of 16 bytes containing the ESP partition unique GUID. That way, the position of these components of VFTM is linked to the GPT table.

## Generation of the keys

Two Sphincs+ keypairs are generated by the Keygen utility. They are named `root` and `manifest`. We use `sk_root` to sign `pk_manifest`, generating the signature `sig_root`. `sig_root` and `pk_root` are injected into the `key.h` header generated by Keygen, alongside the SBFIE stuff. `sk_root` is immediately destroyed and never leave Keygen memory space. Then, using UNIX socket named `vftm.sock`, that should be created in the current directory by the calling entity of Keygen, Keygen transmit the keypair `manifest` to the calling entity. It should always be the entity that will generate the FAT32 filesystem (in this case, VyBuild).

VyBuild will sign the generated manifest with `sk_manifest`, and erase it immediately after. `pk_manifest` became the public key that will be injected into one of the reserved sector of the filesystem, alongside the manifest. The generated `sig_manifest` is injected at the end of the ESP partition, right after the FAT32 manifest.

## Manifest structure

The manifest structure can be represented like this:
``` C
#pragma pack(1)
struct vystem_fat_trusted_manifest {
  uint8_t sig[8];
  uint16_t manifest_version;
  uint16_t bootloader_version;
  uint32_t os_version;
  uint8_t fat_hash[64];
  uint8_t fat_build_id[32];
  uint64_t clusters_count;
  uint64_t bytes_per_sector;
  uint64_t sectors_per_cluster;
  uint64_t fat_size_bytes;
  uint64_t fat_offset_bytes;
  uint64_t bootloader_cluster_count;
  uint64_t bootloader_cluster_offset;
  uint64_t bootloader_build_id;
  uint8_t fat_header_hash[64];
  uint8_t bootloader_binary_hash[64];
  uint64_t signature_offset_bytes;
  uint64_t signature_size;
  uint8_t gpt_disk_guid[16];
  uint8_t gpt_efi_part_unique_guid[16];
  uint8_t manifest_hash[64];
};
#pragma pack()
```

The expected signature is `VyFatSig` in ASCII.

## VFTM detailled verification procedure

Before doing anything, the bootloader will do all these steps to verify the authenticity, then the content of the manifest:

### VFTM assets gathering

The bootloader will gather the following assets in order, using various EDK2 protocols:
- the disk GUID from the GPT header
- the ESP partition unique GUID, that will serve to determine where to extract the manifest and public key
- the manifest and public key
- the manifest signature

### Keys verification

The booloader will then do the following steps to confirm the manifest authenticity:
1) Using `pk_root` and `sig_root`, it verify the extracted `pk_manifest`. If this fail, the bootprocess is halted.
2) Using `pk_manifest` and `sig_manifest`, it verify the extracted manifest. If this fail, the bootprocess is halted.

### Manifest contents verification

Finally, it can use the manifest content to verify various things in this order:
1) Verify the indicated manifest signature, various versions and GUID provided into the manifest.
2) Verify the FAT32 header by comparing his hash and fields with what is provided into the manifest.
3) Verify the FATs by hashing the FATs found in the filesystem and comparing them with the hash provided into the manifest.
4) Verify the bootloader binary by hashing it (retrieving his content through metadatas contained inside the manifest, without using the SimpleFilesystemProtocol) and comparing it to the hash provided into the manifest
5) Verify the hash of the manifest

All hashs use the SHA3-512 algorithm.
