luajitos

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

BARE_METAL.md (6887B)


      1 # Bare Metal LuaJIT Usage Guide
      2 
      3 This cryptography library can be used in bare metal LuaJIT environments without an operating system.
      4 
      5 ## Requirements
      6 
      7 ### 1. Memory Allocator
      8 You must provide a memory allocator. Either:
      9 - Link against a minimal libc that provides `malloc()`, `free()`, `calloc()`, `realloc()`
     10 - **OR** define `USE_CUSTOM_ALLOCATOR` and provide your own allocator
     11 
     12 ### 2. Time/Entropy Sources
     13 You must implement two functions for CSPRNG entropy:
     14 
     15 ```c
     16 uint64_t baremetal_get_ticks(void);   /* Monotonic tick counter */
     17 uint64_t baremetal_get_cycles(void);  /* CPU cycle counter */
     18 ```
     19 
     20 ### 3. Standard String Functions
     21 You need: `memcpy()`, `memset()`, `memmove()`, `memcmp()`, `strlen()`
     22 
     23 Most bare metal environments provide these, or you can implement them easily.
     24 
     25 ## Compilation
     26 
     27 ### Step 1: Define BARE_METAL
     28 Compile with `-DBARE_METAL` flag:
     29 
     30 ```bash
     31 gcc -DBARE_METAL -c crypto.c CSPRNG.c ...
     32 ```
     33 
     34 ### Step 2: Implement Required Functions
     35 
     36 Create a file `baremetal_impl.c`:
     37 
     38 ```c
     39 #include <stdint.h>
     40 
     41 /* Example for x86_64 */
     42 uint64_t baremetal_get_cycles(void) {
     43     uint32_t lo, hi;
     44     __asm__ __volatile__("rdtsc" : "=a"(lo), "=d"(hi));
     45     return ((uint64_t)hi << 32) | lo;
     46 }
     47 
     48 uint64_t baremetal_get_ticks(void) {
     49     /* If you have a timer/PIT/HPET, use it */
     50     /* Otherwise, use CPU cycles as fallback */
     51     return baremetal_get_cycles();
     52 }
     53 ```
     54 
     55 ### Step 3 (Optional): Custom Memory Allocator
     56 
     57 If you don't have malloc/free, define `USE_CUSTOM_ALLOCATOR` and provide:
     58 
     59 ```c
     60 void* baremetal_malloc(size_t size);
     61 void baremetal_free(void *ptr);
     62 void* baremetal_calloc(size_t nmemb, size_t size);
     63 void* baremetal_realloc(void *ptr, size_t size);
     64 ```
     65 
     66 Compile with:
     67 ```bash
     68 gcc -DBARE_METAL -DUSE_CUSTOM_ALLOCATOR ...
     69 ```
     70 
     71 ## Platform-Specific Examples
     72 
     73 ### x86_64 (RDTSC)
     74 
     75 ```c
     76 uint64_t baremetal_get_cycles(void) {
     77     uint32_t lo, hi;
     78     __asm__ __volatile__("rdtsc" : "=a"(lo), "=d"(hi));
     79     return ((uint64_t)hi << 32) | lo;
     80 }
     81 
     82 uint64_t baremetal_get_ticks(void) {
     83     /* Use HPET, PIT, or TSC */
     84     return baremetal_get_cycles();
     85 }
     86 ```
     87 
     88 ### ARM64 (Generic Timer)
     89 
     90 ```c
     91 uint64_t baremetal_get_cycles(void) {
     92     uint64_t val;
     93     __asm__ __volatile__("mrs %0, cntvct_el0" : "=r"(val));
     94     return val;
     95 }
     96 
     97 uint64_t baremetal_get_ticks(void) {
     98     return baremetal_get_cycles();
     99 }
    100 ```
    101 
    102 ### ARM32 (Cortex-A)
    103 
    104 ```c
    105 uint64_t baremetal_get_cycles(void) {
    106     uint32_t val;
    107     __asm__ __volatile__("mrc p15, 0, %0, c9, c13, 0" : "=r"(val));
    108     return val;
    109 }
    110 
    111 uint64_t baremetal_get_ticks(void) {
    112     return baremetal_get_cycles();
    113 }
    114 ```
    115 
    116 ### RISC-V
    117 
    118 ```c
    119 uint64_t baremetal_get_cycles(void) {
    120     uint64_t val;
    121     __asm__ __volatile__("rdcycle %0" : "=r"(val));
    122     return val;
    123 }
    124 
    125 uint64_t baremetal_get_ticks(void) {
    126     return baremetal_get_cycles();
    127 }
    128 ```
    129 
    130 ## Usage in LuaJIT
    131 
    132 Once compiled for bare metal, usage from Lua is identical:
    133 
    134 ```lua
    135 local crypto = require("crypto")
    136 
    137 -- CSPRNG will auto-initialize using your baremetal_get_ticks()
    138 local key = crypto.CSPRNG.newKey()
    139 local nonce = crypto.CSPRNG.randomBytes(12)
    140 
    141 -- All crypto functions work normally
    142 local plaintext = "Hello, bare metal!"
    143 local encrypted = crypto.ChaCha20.encrypt(key, plaintext)
    144 local decrypted = crypto.ChaCha20.decrypt(key, encrypted)
    145 ```
    146 
    147 ## What Gets Disabled in Bare Metal Mode
    148 
    149 When `BARE_METAL` is defined:
    150 - `fprintf()`, `printf()`, `perror()` → stubbed out (do nothing)
    151 - `clock_gettime()` → redirects to your `baremetal_get_ticks()`
    152 - `time()` → redirects to your `baremetal_get_ticks()`
    153 
    154 ## Security Considerations
    155 
    156 ### Entropy Quality
    157 The security of the CSPRNG depends on your entropy sources:
    158 
    159 **Good entropy sources:**
    160 - High-resolution CPU cycle counter (RDTSC, CNTVCT, etc.)
    161 - Hardware random number generator (RDRAND, RDSEED on x86)
    162 - Timer interrupts with jitter
    163 - DMA timing variations
    164 - Cache timing
    165 
    166 **Poor entropy sources:**
    167 - Simple counters without jitter
    168 - Predictable timers
    169 - Deterministic values
    170 
    171 ### Example: Using RDRAND (x86)
    172 
    173 ```c
    174 uint64_t baremetal_get_cycles(void) {
    175     uint64_t val;
    176     /* Try RDRAND first */
    177     if (__builtin_cpu_supports("rdrnd")) {
    178         __asm__ __volatile__("rdrand %0" : "=r"(val));
    179         return val;
    180     }
    181     /* Fall back to RDTSC */
    182     uint32_t lo, hi;
    183     __asm__ __volatile__("rdtsc" : "=a"(lo), "=d"(hi));
    184     return ((uint64_t)hi << 32) | lo;
    185 }
    186 ```
    187 
    188 ## Testing Bare Metal Build
    189 
    190 ```bash
    191 # Compile with bare metal flag
    192 gcc -DBARE_METAL -c CSPRNG.c -o CSPRNG.o
    193 
    194 # Link with your bare metal implementation
    195 gcc -DBARE_METAL -o test_crypto \
    196     crypto.o CSPRNG.o baremetal_impl.o \
    197     -llua -lgmp -lm
    198 
    199 # Or for LuaJIT shared library
    200 gcc -DBARE_METAL -shared -fPIC \
    201     crypto.c CSPRNG.c baremetal_impl.c \
    202     -o crypto.so -lgmp
    203 ```
    204 
    205 ## Minimal Example
    206 
    207 Here's a complete minimal example for x86_64:
    208 
    209 **baremetal_impl.c:**
    210 ```c
    211 #include <stdint.h>
    212 
    213 uint64_t baremetal_get_cycles(void) {
    214     uint32_t lo, hi;
    215     __asm__ __volatile__("rdtsc" : "=a"(lo), "=d"(hi));
    216     return ((uint64_t)hi << 32) | lo;
    217 }
    218 
    219 uint64_t baremetal_get_ticks(void) {
    220     return baremetal_get_cycles();
    221 }
    222 ```
    223 
    224 **Compile:**
    225 ```bash
    226 # Compile all crypto sources with BARE_METAL
    227 gcc -DBARE_METAL -shared -fPIC \
    228     crypto.c CSPRNG.c CSPRNG_Lua.c \
    229     Hash_Lua.c PBKDF2_Lua.c \
    230     X25519_Lua.c Ed25519_Lua.c \
    231     RSA_Lua.c RSA_production.c \
    232     P256_Lua.c P256.c \
    233     hashing/*.c \
    234     baremetal_impl.c \
    235     -o crypto.so -lluajit -lgmp
    236 ```
    237 
    238 **Use in LuaJIT:**
    239 ```lua
    240 local crypto = require("crypto")
    241 print("Bare metal crypto initialized!")
    242 
    243 local key = crypto.CSPRNG.newKey(256)
    244 print("Generated key:", key)
    245 ```
    246 
    247 ## Notes
    248 
    249 1. **Memory**: Ensure you have enough heap space for RSA operations (they can allocate several KB)
    250 2. **Stack**: Deep recursion in some algorithms may require larger stack
    251 3. **FPU**: Not required - all operations use integer math
    252 4. **Threading**: Not thread-safe by default - use locks if needed
    253 5. **Performance**: Hardware AES-NI and PCLMULQDQ are used when available
    254 
    255 ## Troubleshooting
    256 
    257 ### "undefined reference to baremetal_get_ticks"
    258 You forgot to implement the required functions or link `baremetal_impl.o`
    259 
    260 ### "undefined reference to malloc"
    261 Link against a libc or define `USE_CUSTOM_ALLOCATOR`
    262 
    263 ### Weak entropy warnings
    264 Your `baremetal_get_ticks()` returns constant values - implement proper timer
    265 
    266 ### Segmentation fault
    267 Check your memory allocator and stack size
    268 
    269 ## Summary
    270 
    271 To use this crypto library in bare metal LuaJIT:
    272 
    273 ✅ **Required:**
    274 1. Define `BARE_METAL` during compilation
    275 2. Implement `baremetal_get_ticks()` and `baremetal_get_cycles()`
    276 3. Provide memory allocator (malloc/free) or use custom
    277 4. Link against LuaJIT and GMP
    278 
    279 ✅ **Optional:**
    280 - Hardware crypto acceleration (AES-NI, PCLMULQDQ)
    281 - Hardware RNG (RDRAND, RDSEED)
    282 
    283 ✅ **Result:**
    284 - Full cryptographic library in bare metal environment
    285 - No OS dependencies
    286 - Works with your custom timer/entropy sources