DVX_GUI/security/README.md

259 lines
7 KiB
Markdown

# Security — DH Key Exchange and XTEA-CTR Cipher
Cryptographic library providing Diffie-Hellman key exchange and XTEA
symmetric encryption, optimized for 486-class DOS hardware running
under DJGPP/DPMI.
## Components
### Diffie-Hellman Key Exchange
- 1024-bit MODP group (RFC 2409 Group 2 safe prime)
- 256-bit private exponents for fast computation on 486 CPUs
- Montgomery multiplication (CIOS variant) for modular exponentiation
- Lazy-initialized Montgomery constants (R^2 mod p, -p0^-1 mod 2^32)
### XTEA Cipher (CTR Mode)
- 128-bit key, 64-bit block size, 32 rounds
- CTR mode — encrypt and decrypt are the same XOR operation
- No lookup tables, no key schedule — just shifts, adds, and XORs
- Ideal for constrained environments with small key setup cost
### Pseudo-Random Number Generator
- XTEA-CTR based DRBG (deterministic random bit generator)
- Hardware entropy from PIT counter (~10 bits) and BIOS tick count
- Supports additional entropy injection (keyboard timing, mouse, etc.)
- Auto-seeds from hardware on first use if not explicitly seeded
## Performance
At serial port speeds, encryption overhead is minimal:
| Speed | Blocks/sec | CPU cycles/sec | % of 33 MHz 486 |
|----------|------------|----------------|------------------|
| 9600 | 120 | ~240K | < 1% |
| 57600 | 720 | ~1.4M | ~4% |
| 115200 | 1440 | ~2.9M | ~9% |
DH key exchange takes approximately 0.3s at 66 MHz or 0.6s at 33 MHz
(256-bit private exponent, 1024-bit modulus).
## API Reference
### Constants
| Name | Value | Description |
|---------------------|-------|--------------------------------|
| `SEC_DH_KEY_SIZE` | 128 | DH public key size (bytes) |
| `SEC_XTEA_KEY_SIZE` | 16 | XTEA key size (bytes) |
| `SEC_SUCCESS` | 0 | Success |
| `SEC_ERR_PARAM` | -1 | Invalid parameter |
| `SEC_ERR_NOT_READY` | -2 | Keys not yet generated/derived |
| `SEC_ERR_ALLOC` | -3 | Memory allocation failed |
### Types
```c
typedef struct SecDhS SecDhT; // Opaque DH context
typedef struct SecCipherS SecCipherT; // Opaque cipher context
```
### RNG Functions
```c
int secRngGatherEntropy(uint8_t *buf, int len);
```
Reads hardware entropy sources (PIT counter, BIOS tick count). Returns
the number of bytes written. Provides roughly 20 bits of true entropy.
```c
void secRngSeed(const uint8_t *entropy, int len);
```
Initializes the DRBG with the given entropy. XOR-folds the input into
the XTEA key, derives the counter, and mixes state by generating and
discarding 64 bytes.
```c
void secRngAddEntropy(const uint8_t *data, int len);
```
Mixes additional entropy into the running RNG state without resetting
it. Use this to stir in keyboard timing, mouse jitter, or other
runtime entropy.
```c
void secRngBytes(uint8_t *buf, int len);
```
Generates `len` pseudo-random bytes. Auto-seeds from hardware if not
previously seeded.
### Diffie-Hellman Functions
```c
SecDhT *secDhCreate(void);
```
Allocates a new DH context. Returns `NULL` on allocation failure.
```c
int secDhGenerateKeys(SecDhT *dh);
```
Generates a 256-bit random private key and computes the corresponding
1024-bit public key (g^private mod p). The RNG should be seeded first.
```c
int secDhGetPublicKey(SecDhT *dh, uint8_t *buf, int *len);
```
Exports the public key into `buf`. On entry, `*len` must be at least
`SEC_DH_KEY_SIZE` (128). On return, `*len` is set to 128.
```c
int secDhComputeSecret(SecDhT *dh, const uint8_t *remotePub, int len);
```
Computes the shared secret from the remote side's public key.
Validates that the remote key is in range [2, p-2] to prevent
small-subgroup attacks.
```c
int secDhDeriveKey(SecDhT *dh, uint8_t *key, int keyLen);
```
Derives a symmetric key by XOR-folding the 128-byte shared secret
down to `keyLen` bytes.
```c
void secDhDestroy(SecDhT *dh);
```
Securely zeroes and frees the DH context (private key, shared secret).
### Cipher Functions
```c
SecCipherT *secCipherCreate(const uint8_t *key);
```
Creates an XTEA-CTR cipher context with the given 16-byte key. Counter
starts at zero.
```c
void secCipherCrypt(SecCipherT *c, uint8_t *data, int len);
```
Encrypts or decrypts `data` in place. CTR mode is symmetric the
same operation encrypts and decrypts.
```c
void secCipherSetNonce(SecCipherT *c, uint32_t nonceLo, uint32_t nonceHi);
```
Sets the 64-bit nonce/counter. Call before encrypting if you need a
specific starting counter value.
```c
void secCipherDestroy(SecCipherT *c);
```
Securely zeroes and frees the cipher context.
## Example
### Full Key Exchange
```c
#include "security.h"
#include <string.h>
// Seed the RNG
uint8_t entropy[16];
secRngGatherEntropy(entropy, sizeof(entropy));
secRngSeed(entropy, sizeof(entropy));
// Create DH context and generate keys
SecDhT *dh = secDhCreate();
secDhGenerateKeys(dh);
// Export public key to send to remote
uint8_t myPub[SEC_DH_KEY_SIZE];
int pubLen = SEC_DH_KEY_SIZE;
secDhGetPublicKey(dh, myPub, &pubLen);
// ... send myPub to remote, receive remotePub ...
// Compute shared secret and derive a 16-byte key
secDhComputeSecret(dh, remotePub, SEC_DH_KEY_SIZE);
uint8_t key[SEC_XTEA_KEY_SIZE];
secDhDeriveKey(dh, key, SEC_XTEA_KEY_SIZE);
secDhDestroy(dh);
// Create cipher and encrypt
SecCipherT *cipher = secCipherCreate(key);
uint8_t message[] = "Secret message";
secCipherCrypt(cipher, message, sizeof(message));
// message is now encrypted
// Decrypt (same operation — CTR mode is symmetric)
// Reset counter first if using the same cipher context
secCipherSetNonce(cipher, 0, 0);
secCipherCrypt(cipher, message, sizeof(message));
// message is now plaintext again
secCipherDestroy(cipher);
```
### Standalone Encryption
```c
// XTEA-CTR can be used independently of DH
uint8_t key[SEC_XTEA_KEY_SIZE] = { /* your key */ };
SecCipherT *c = secCipherCreate(key);
uint8_t data[1024];
// ... fill data ...
secCipherCrypt(c, data, sizeof(data)); // encrypt in place
secCipherDestroy(c);
```
## Implementation Details
### BigNum Arithmetic
All modular arithmetic uses a 1024-bit big number type (`BigNumT`)
stored as 32 x `uint32_t` words in little-endian order. Operations:
- Add, subtract, compare, shift-left-1, bit test
- Montgomery multiplication (CIOS with implicit right-shift)
- Modular exponentiation (left-to-right binary square-and-multiply)
### Montgomery Multiplication
The CIOS (Coarsely Integrated Operand Scanning) variant computes
`a * b * R^-1 mod m` in a single pass with implicit division by the
word base. Constants are computed once on first DH use:
- `R^2 mod p` via 2048 iterations of shift-and-conditional-subtract
- `-p[0]^-1 mod 2^32` via Newton's method (5 iterations)
### Secure Zeroing
Key material is erased using a volatile-pointer loop that the compiler
cannot optimize away, preventing sensitive data from lingering in
memory.
## Building
```
make # builds ../lib/libsecurity.a
make clean # removes objects and library
```
Target: DJGPP cross-compiler, 486+ CPU.