Security Mechanisms

The WvdS Crypto Service implements several protection mechanisms that are automatically active. You don't need to configure anything.


Rate Limiting

Protects against Denial-of-Service (DoS) attacks through overload.

Parameter Value
Max Requests/Second 1000
Burst Tolerance 100
Cooldown 100 ms

Behavior when exceeded:

Request --> [Rate Limiter] --> Status: 0x07 (RATE_LIMITED)
                           --> No crypto operation performed

Client Recommendation:

int send_with_retry(const uint8_t* request, size_t len) {
    int retry = 0;
    int delay_ms = 100;
 
    while (retry < 5) {
        send_request(request, len);
        int status = get_response_status();
 
        if (status != 0x07) return status;  // Not rate-limited
 
        usleep(delay_ms * 1000);
        delay_ms *= 2;  // Exponential backoff
        retry++;
    }
    return -1;  // Timeout
}

Nonce Tracking

Nonce Reuse = Catastrophe

With AES-GCM, reusing a nonce leads to complete compromise of both plaintexts!

The Crypto Service actively protects against nonce reuse:

For Encrypt

For Decrypt

Note: Nonce tracking is per Key-ID. The tracker is reset on key rotation.


Input Validation

All inputs are validated before processing:

Check Error Code
Magic Byte != 0xC7 0x01 (INVALID_HEADER)
Unknown Request-Type 0x02 (INVALID_TYPE)
Payload length wrong 0x03 (INVALID_PAYLOAD)
Key-ID doesn't exist 0x04 (KEY_NOT_FOUND)
Payload > 64 KB 0x09 (PAYLOAD_TOO_LARGE)

No Exceptions:

The service doesn't throw exceptions. All errors are returned via status codes.


Max Payload Size

Limit 64 KB (65536 bytes)

Reasons:

Encrypting large data:

// Chunked Encryption for large files
#define CHUNK_SIZE (60 * 1024)  // 60 KB per chunk
 
int encrypt_large_file(FILE* in, FILE* out) {
    uint8_t buffer[CHUNK_SIZE];
    size_t bytes_read;
    uint32_t chunk_id = 0;
 
    while ((bytes_read = fread(buffer, 1, CHUNK_SIZE, in)) > 0) {
        // AAD contains Chunk-ID for ordering protection
        char aad[32];
        snprintf(aad, sizeof(aad), "chunk:%u", chunk_id++);
 
        uint8_t ct[CHUNK_SIZE + 28];
        size_t ct_len;
        uint8_t nonce[12], tag[16];
 
        encrypt_message(buffer, bytes_read, aad, strlen(aad),
                       ct, &ct_len, nonce, tag);
 
        fwrite(nonce, 1, 12, out);
        fwrite(tag, 1, 16, out);
        fwrite(ct, 1, ct_len, out);
    }
    return 0;
}

Zeroize on Drop

All security-critical data is overwritten after use:

Implementation:

// Prevent compiler optimization
static void secure_zero(void* ptr, size_t len) {
    volatile uint8_t* p = (volatile uint8_t*)ptr;
    while (len--) *p++ = 0;
}

L4Re Isolation

The Crypto Service runs as an isolated L4Re task:

+---------------------------------------------------------------+
|                    L4Re Microkernel                           |
+---------------------------------------------------------------+
|     |              |              |              |            |
|  +--+--+       +---+---+      +---+---+      +---+---+        |
|  | Sigma0 |    | Moe   |      | Crypto |     | OEM   |        |
|  | (Root) |    | (Mem) |      | Service|     | Gateway|       |
|  +--------+    +-------+      +--------+     +--------+        |
|                                   |              |             |
|                                   +--------------+             |
|                                   ONLY this IPC                |
+---------------------------------------------------------------+

Security Guarantees:


Troubleshooting

Symptom Possible Cause Solution
Status 0x04 persistent Key storage corrupt Regenerate keys
Status 0x07 frequent Request rate too high Batching, caching
Status 0x08 Key rotation forgotten Generate new key
Slow performance FIPS mode + Debug Use release build
Memory leak Responses not processed Clear shared memory

< API Reference | Next: Compliance >