luajitos

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

fde.h (10170B)


      1 /* FDE - Full Disk Encryption for LuajitOS
      2  *
      3  * Provides transparent disk encryption using cascaded ciphers:
      4  * AES-256-GCM (inner) + XChaCha20-Poly1305 (outer)
      5  *
      6  * Features:
      7  * - Cascaded encryption for defense in depth
      8  * - Per-sector encryption with unique nonces
      9  * - Argon2id key derivation (memory-hard)
     10  * - Integrity verification via auth tags
     11  * - Random-access read/write support
     12  */
     13 
     14 #ifndef FDE_H
     15 #define FDE_H
     16 
     17 #include <stdint.h>
     18 #include <stddef.h>
     19 
     20 #ifdef __cplusplus
     21 extern "C" {
     22 #endif
     23 
     24 /* ============================================================================
     25  * Constants
     26  * ========================================================================= */
     27 
     28 #define FDE_MAGIC           "LJOS_FDE"
     29 #define FDE_MAGIC_SIZE      8
     30 #define FDE_VERSION         1
     31 
     32 #define FDE_SECTOR_SIZE     512
     33 #define FDE_KEY_SIZE        32      /* 256 bits per cipher */
     34 #define FDE_MASTER_KEY_SIZE 64      /* Two 256-bit keys */
     35 #define FDE_SALT_SIZE       32
     36 #define FDE_NONCE_AES_SIZE  12      /* AES-GCM nonce */
     37 #define FDE_NONCE_XCHACHA_SIZE 24   /* XChaCha20 nonce */
     38 #define FDE_TAG_SIZE        16      /* Auth tag size per cipher */
     39 #define FDE_TAGS_PER_SECTOR 32      /* 16 + 16 bytes for both tags */
     40 
     41 /* Header is stored in sector 0 */
     42 #define FDE_HEADER_SECTOR   0
     43 
     44 /* KDF parameters */
     45 #define FDE_KDF_MEMORY      4096    /* 4 MB for Argon2id (reduced for bare metal) */
     46 #define FDE_KDF_TIME        3       /* 3 iterations */
     47 #define FDE_KDF_PARALLELISM 1       /* Single-threaded for bare metal */
     48 #define FDE_KDF_ITERATIONS_DEFAULT 100000  /* For PBKDF2 fallback */
     49 
     50 /* Cipher modes */
     51 #define FDE_CIPHER_NONE         0   /* No encryption (plaintext) */
     52 #define FDE_CIPHER_AES_GCM      1   /* AES-256-GCM only */
     53 #define FDE_CIPHER_XCHACHA      2   /* XChaCha20-Poly1305 only */
     54 #define FDE_CIPHER_CASCADE      3   /* AES-256-GCM + XChaCha20-Poly1305 */
     55 
     56 /* Error codes */
     57 #define FDE_OK                  0
     58 #define FDE_ERR_INVALID_PARAM   -1
     59 #define FDE_ERR_NO_MEMORY       -2
     60 #define FDE_ERR_IO              -3
     61 #define FDE_ERR_CRYPTO          -4
     62 #define FDE_ERR_BAD_PASSWORD    -5
     63 #define FDE_ERR_CORRUPT         -6
     64 #define FDE_ERR_NOT_FORMATTED   -7
     65 #define FDE_ERR_ALREADY_OPEN    -8
     66 #define FDE_ERR_NOT_OPEN        -9
     67 #define FDE_ERR_AUTH_FAILED     -10
     68 
     69 /* ============================================================================
     70  * Structures
     71  * ========================================================================= */
     72 
     73 /* Disk header (stored in sector 0) - 512 bytes */
     74 /* NOTE: header_hash MUST be at the end so sha256 can hash everything before it */
     75 typedef struct __attribute__((packed)) {
     76     char        magic[FDE_MAGIC_SIZE];      /* "LJOS_FDE" */
     77     uint32_t    version;                    /* Header version */
     78     uint32_t    cipher_mode;                /* Cipher mode (0-3) */
     79     uint32_t    kdf_iterations;             /* KDF iteration count */
     80     uint32_t    total_sectors;              /* Total sectors on disk */
     81     uint32_t    data_start_sector;          /* First data sector */
     82     uint32_t    tag_start_sector;           /* First tag sector */
     83     uint8_t     salt[FDE_SALT_SIZE];        /* KDF salt */
     84     uint8_t     encrypted_master_key[FDE_MASTER_KEY_SIZE + FDE_TAG_SIZE * 2];
     85                                             /* Encrypted master key + tags */
     86     uint8_t     reserved[512 - 8 - 4*6 - 32 - (64+32) - 32];  /* Padding to 512 */
     87     uint8_t     header_hash[32];            /* SHA-256 of header (excluding this field) - MUST BE LAST */
     88 } fde_header_t;
     89 
     90 /* FDE context (runtime state) */
     91 typedef struct {
     92     uint8_t     bus;                        /* ATA bus */
     93     uint8_t     drive;                      /* ATA drive */
     94     uint8_t     is_open;                    /* Is disk open? */
     95     uint8_t     cipher_mode;                /* Active cipher mode */
     96     uint32_t    partition_start;            /* Start sector of partition (0 if whole disk) */
     97     uint32_t    partition_size;             /* Size of partition in sectors */
     98     uint32_t    total_sectors;              /* Total usable data sectors */
     99     uint32_t    data_start_sector;          /* First data sector (relative to partition) */
    100     uint32_t    tag_start_sector;           /* First tag sector (relative to partition) */
    101     uint8_t     aes_key[FDE_KEY_SIZE];      /* AES-256 key */
    102     uint8_t     xchacha_key[FDE_KEY_SIZE];  /* XChaCha20 key */
    103 } fde_context_t;
    104 
    105 /* Sector tags (stored in tag area) */
    106 typedef struct __attribute__((packed)) {
    107     uint8_t     aes_tag[FDE_TAG_SIZE];      /* AES-GCM auth tag */
    108     uint8_t     xchacha_tag[FDE_TAG_SIZE];  /* XChaCha20 auth tag */
    109 } fde_sector_tags_t;
    110 
    111 /* ============================================================================
    112  * API Functions
    113  * ========================================================================= */
    114 
    115 /**
    116  * Format a disk/partition with FDE
    117  *
    118  * @param bus           ATA bus (0 = primary, 1 = secondary)
    119  * @param drive         ATA drive (0 = master, 1 = slave)
    120  * @param password      Encryption password
    121  * @param pass_len      Password length
    122  * @param cipher        Cipher mode (FDE_CIPHER_*)
    123  * @return              FDE_OK on success, error code on failure
    124  */
    125 int fde_format(uint8_t bus, uint8_t drive,
    126                const char *password, size_t pass_len,
    127                uint8_t cipher);
    128 
    129 /**
    130  * Format a partition with FDE
    131  *
    132  * @param bus           ATA bus (0 = primary, 1 = secondary)
    133  * @param drive         ATA drive (0 = master, 1 = slave)
    134  * @param part_start    Partition start sector
    135  * @param part_size     Partition size in sectors
    136  * @param password      Encryption password
    137  * @param pass_len      Password length
    138  * @param cipher        Cipher mode (FDE_CIPHER_*)
    139  * @return              FDE_OK on success, error code on failure
    140  */
    141 int fde_format_partition(uint8_t bus, uint8_t drive,
    142                          uint32_t part_start, uint32_t part_size,
    143                          const char *password, size_t pass_len,
    144                          uint8_t cipher);
    145 
    146 /**
    147  * Open an encrypted disk
    148  *
    149  * @param ctx       Context to initialize
    150  * @param bus       ATA bus
    151  * @param drive     ATA drive
    152  * @param password  Encryption password
    153  * @param pass_len  Password length
    154  * @return          FDE_OK on success, error code on failure
    155  */
    156 int fde_open(fde_context_t *ctx, uint8_t bus, uint8_t drive,
    157              const char *password, size_t pass_len);
    158 
    159 /**
    160  * Open an encrypted partition
    161  *
    162  * @param ctx           Context to initialize
    163  * @param bus           ATA bus
    164  * @param drive         ATA drive
    165  * @param part_start    Partition start sector
    166  * @param password      Encryption password
    167  * @param pass_len      Password length
    168  * @return              FDE_OK on success, error code on failure
    169  */
    170 int fde_open_partition(fde_context_t *ctx, uint8_t bus, uint8_t drive,
    171                        uint32_t part_start,
    172                        const char *password, size_t pass_len);
    173 
    174 /**
    175  * Close an encrypted disk
    176  *
    177  * @param ctx       Context to close
    178  * @return          FDE_OK on success, error code on failure
    179  */
    180 int fde_close(fde_context_t *ctx);
    181 
    182 /**
    183  * Read a decrypted sector
    184  *
    185  * @param ctx       Open FDE context
    186  * @param sector    Logical sector number (0-based, in data area)
    187  * @param buffer    Output buffer (512 bytes)
    188  * @return          FDE_OK on success, error code on failure
    189  */
    190 int fde_read_sector(fde_context_t *ctx, uint32_t sector, void *buffer);
    191 
    192 /**
    193  * Write and encrypt a sector
    194  *
    195  * @param ctx       Open FDE context
    196  * @param sector    Logical sector number (0-based, in data area)
    197  * @param buffer    Input buffer (512 bytes)
    198  * @return          FDE_OK on success, error code on failure
    199  */
    200 int fde_write_sector(fde_context_t *ctx, uint32_t sector, const void *buffer);
    201 
    202 /**
    203  * Read multiple decrypted sectors
    204  *
    205  * @param ctx       Open FDE context
    206  * @param start     Starting logical sector
    207  * @param count     Number of sectors to read
    208  * @param buffer    Output buffer (count * 512 bytes)
    209  * @return          FDE_OK on success, error code on failure
    210  */
    211 int fde_read_sectors(fde_context_t *ctx, uint32_t start, uint32_t count, void *buffer);
    212 
    213 /**
    214  * Write and encrypt multiple sectors
    215  *
    216  * @param ctx       Open FDE context
    217  * @param start     Starting logical sector
    218  * @param count     Number of sectors to write
    219  * @param buffer    Input buffer (count * 512 bytes)
    220  * @return          FDE_OK on success, error code on failure
    221  */
    222 int fde_write_sectors(fde_context_t *ctx, uint32_t start, uint32_t count, const void *buffer);
    223 
    224 /**
    225  * Get information about an encrypted disk
    226  *
    227  * @param bus       ATA bus
    228  * @param drive     ATA drive
    229  * @param cipher    Output: cipher mode
    230  * @param sectors   Output: total data sectors
    231  * @return          FDE_OK if disk is FDE formatted, error otherwise
    232  */
    233 int fde_get_info(uint8_t bus, uint8_t drive, uint8_t *cipher, uint32_t *sectors);
    234 
    235 /**
    236  * Check if a disk is FDE formatted
    237  *
    238  * @param bus       ATA bus
    239  * @param drive     ATA drive
    240  * @return          1 if FDE formatted, 0 otherwise
    241  */
    242 int fde_is_formatted(uint8_t bus, uint8_t drive);
    243 
    244 /**
    245  * Change the password on an encrypted disk
    246  *
    247  * @param ctx           Open FDE context
    248  * @param old_password  Current password
    249  * @param old_len       Current password length
    250  * @param new_password  New password
    251  * @param new_len       New password length
    252  * @return              FDE_OK on success, error code on failure
    253  */
    254 int fde_change_password(fde_context_t *ctx,
    255                         const char *old_password, size_t old_len,
    256                         const char *new_password, size_t new_len);
    257 
    258 /**
    259  * Get error string for error code
    260  *
    261  * @param error     Error code
    262  * @return          Human-readable error string
    263  */
    264 const char *fde_error_string(int error);
    265 
    266 /**
    267  * Get cipher mode name
    268  *
    269  * @param cipher    Cipher mode
    270  * @return          Cipher name string
    271  */
    272 const char *fde_cipher_name(uint8_t cipher);
    273 
    274 /* ============================================================================
    275  * Lua Bindings
    276  * ========================================================================= */
    277 
    278 struct lua_State;
    279 int luaopen_fde(struct lua_State *L);
    280 
    281 #ifdef __cplusplus
    282 }
    283 #endif
    284 
    285 #endif /* FDE_H */