luajitos

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

example_persistence.c (6430B)


      1 /*
      2  * Example: Saving and Loading Encrypted Data
      3  *
      4  * Demonstrates how to:
      5  * 1. Encrypt data
      6  * 2. Serialize it to bytes
      7  * 3. Save to a file
      8  * 4. Load from file after restart
      9  * 5. Deserialize and decrypt
     10  */
     11 
     12 #include "EasyCrypto.h"
     13 #include "CSPRNG.h"
     14 #include <stdio.h>
     15 #include <string.h>
     16 #include <fcntl.h>
     17 #include <unistd.h>
     18 
     19 /* Save bytes to file */
     20 int save_to_file(const char *filename, const uint8_t *data, size_t len) {
     21     int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
     22     if (fd < 0) {
     23         perror("Failed to open file for writing");
     24         return -1;
     25     }
     26 
     27     ssize_t written = write(fd, data, len);
     28     close(fd);
     29 
     30     if (written != (ssize_t)len) {
     31         fprintf(stderr, "Failed to write all data to file\n");
     32         return -1;
     33     }
     34 
     35     return 0;
     36 }
     37 
     38 /* Load bytes from file */
     39 uint8_t* load_from_file(const char *filename, size_t *len) {
     40     int fd = open(filename, O_RDONLY);
     41     if (fd < 0) {
     42         perror("Failed to open file for reading");
     43         return NULL;
     44     }
     45 
     46     /* Get file size */
     47     off_t file_size = lseek(fd, 0, SEEK_END);
     48     if (file_size < 0) {
     49         close(fd);
     50         return NULL;
     51     }
     52     lseek(fd, 0, SEEK_SET);
     53 
     54     /* Allocate buffer */
     55     uint8_t *buffer = malloc(file_size);
     56     if (!buffer) {
     57         close(fd);
     58         return NULL;
     59     }
     60 
     61     /* Read file */
     62     ssize_t bytes_read = read(fd, buffer, file_size);
     63     close(fd);
     64 
     65     if (bytes_read != file_size) {
     66         free(buffer);
     67         return NULL;
     68     }
     69 
     70     *len = file_size;
     71     return buffer;
     72 }
     73 
     74 int main(void) {
     75     printf("╔════════════════════════════════════════════════════╗\n");
     76     printf("║   Encrypted Data Persistence Example              ║\n");
     77     printf("╚════════════════════════════════════════════════════╝\n\n");
     78 
     79     /* Initialize CSPRNG */
     80     csprng_global_init();
     81 
     82     /* Generate encryption key */
     83     uint8_t key[32];
     84     random_bytes(key, 32);
     85 
     86     printf("Step 1: Generate encryption key\n");
     87     printf("Key: ");
     88     for (int i = 0; i < 16; i++) printf("%02x", key[i]);
     89     printf("...\n\n");
     90 
     91     /* Data to encrypt */
     92     const char *secret_message = "This is confidential data that needs to survive a reboot!";
     93     printf("Step 2: Original message\n");
     94     printf("\"%s\"\n\n", secret_message);
     95 
     96     /* Encrypt the data */
     97     printf("Step 3: Encrypt with Twofish-256-GCM\n");
     98     size_t encrypted_len;
     99     void *encrypted = ENCRYPT_TWOFISH(key, (uint8_t*)secret_message, strlen(secret_message), &encrypted_len);
    100     if (!encrypted) {
    101         fprintf(stderr, "✗ Encryption failed\n");
    102         return 1;
    103     }
    104     printf("✓ Encrypted successfully\n");
    105     printf("  Format: [Nonce(12)][Tag(16)][Ciphertext(var)]\n");
    106     printf("  Total length: %zu bytes\n", encrypted_len);
    107     printf("  Breakdown:\n");
    108     printf("    - Nonce: 12 bytes\n");
    109     printf("    - Tag: 16 bytes\n");
    110     printf("    - Ciphertext: %zu bytes\n\n", encrypted_len - 28);
    111 
    112     /* Save to file */
    113     printf("Step 4: Save to file 'encrypted_data.bin'\n");
    114     if (save_to_file("encrypted_data.bin", encrypted, encrypted_len) != 0) {
    115         fprintf(stderr, "✗ Failed to save to file\n");
    116         free(encrypted);
    117         return 1;
    118     }
    119     printf("✓ Saved %zu bytes to encrypted_data.bin\n", encrypted_len);
    120     printf("  First 32 bytes: ");
    121     for (size_t i = 0; i < 32 && i < encrypted_len; i++) {
    122         printf("%02x", ((uint8_t*)encrypted)[i]);
    123     }
    124     printf("...\n\n");
    125 
    126     /* Clean up */
    127     free(encrypted);
    128 
    129     printf("════════════════════════════════════════════════════\n");
    130     printf("SIMULATING RESTART - All memory is cleared\n");
    131     printf("════════════════════════════════════════════════════\n\n");
    132 
    133     /* Load from file */
    134     printf("Step 5: Load from file after 'restart'\n");
    135     size_t loaded_len;
    136     uint8_t *loaded = load_from_file("encrypted_data.bin", &loaded_len);
    137     if (!loaded) {
    138         fprintf(stderr, "✗ Failed to load from file\n");
    139         return 1;
    140     }
    141     printf("✓ Loaded %zu bytes from encrypted_data.bin\n", loaded_len);
    142     printf("  Format: [Nonce(12)][Tag(16)][Ciphertext(%zu)]\n", loaded_len - 28);
    143     printf("  First 32 bytes: ");
    144     for (size_t i = 0; i < 32 && i < loaded_len; i++) {
    145         printf("%02x", loaded[i]);
    146     }
    147     printf("...\n\n");
    148 
    149     /* Decrypt */
    150     printf("Step 6: Decrypt using the same key\n");
    151     size_t decrypted_len;
    152     void *decrypted = DECRYPT_TWOFISH(key, loaded, loaded_len, &decrypted_len);
    153     free(loaded);
    154 
    155     if (!decrypted) {
    156         fprintf(stderr, "✗ Decryption failed\n");
    157         return 1;
    158     }
    159 
    160     printf("✓ Decrypted successfully\n");
    161     printf("  Recovered message: \"");
    162     fwrite(decrypted, 1, decrypted_len, stdout);
    163     printf("\"\n\n");
    164 
    165     /* Verify */
    166     if (decrypted_len == strlen(secret_message) &&
    167         memcmp(decrypted, secret_message, decrypted_len) == 0) {
    168         printf("✓ SUCCESS! Message survived the 'restart'\n\n");
    169     } else {
    170         printf("✗ FAILED! Message was corrupted\n\n");
    171     }
    172 
    173     free(decrypted);
    174 
    175     /* Clean up */
    176     unlink("encrypted_data.bin");
    177 
    178     printf("════════════════════════════════════════════════════\n");
    179     printf("Key Points:\n");
    180     printf("════════════════════════════════════════════════════\n");
    181     printf("• ENCRYPT_TWOFISH returns void* with [Nonce][Tag][Ciphertext]\n");
    182     printf("• Format: [Nonce(12)][Tag(16)][Ciphertext(var)]\n");
    183     printf("• NO metadata - algorithm/lengths tracked externally\n");
    184     printf("• Direct to bytes - no serialization needed\n");
    185     printf("• Save bytes directly to disk/database/network\n");
    186     printf("• DECRYPT_TWOFISH reads the same format\n");
    187     printf("• Simple API: just encrypt, save, load, decrypt\n\n");
    188 
    189     /* Zero sensitive data */
    190     memset(key, 0, 32);
    191 
    192     return 0;
    193 }