74 lines
3.1 KiB
C
74 lines
3.1 KiB
C
// Security library: Diffie-Hellman key exchange + XTEA-CTR cipher
|
|
// Targets 486-class hardware with 1024-bit DH (256-bit private exponent)
|
|
// and XTEA in CTR mode for symmetric encryption.
|
|
//
|
|
// Why XTEA instead of AES/DES:
|
|
// XTEA requires zero lookup tables, no key schedule, and compiles to
|
|
// ~20 instructions per round (shifts, adds, XORs). This makes it ideal
|
|
// for a 486 where cache is tiny (8KB) and AES's 4KB S-boxes would
|
|
// thrash it. DES is similarly table-heavy and also has a complex key
|
|
// schedule. XTEA has no library dependencies — the entire cipher fits
|
|
// in a dozen lines of C. At 32 rounds, XTEA provides 128-bit security
|
|
// with negligible per-byte cost on even the slowest target hardware.
|
|
//
|
|
// Why 1024-bit DH with 256-bit private exponent:
|
|
// RFC 2409 Group 2 provides interoperability and a well-audited safe
|
|
// prime. 256-bit private exponents (vs full 1024-bit) reduce the modular
|
|
// exponentiation from ~1024 squarings+multiplies to ~256, making key
|
|
// generation feasible on a 486 in seconds rather than minutes. The
|
|
// security reduction is negligible (Pollard's rho on 256-bit exponent
|
|
// is ~2^128 operations, same as XTEA's key strength).
|
|
//
|
|
// RNG:
|
|
// XTEA-CTR DRBG seeded from PIT timer jitter and BIOS tick count.
|
|
// Hardware entropy is weak (~20 bits from PIT), so callers should
|
|
// supplement with user-generated entropy (keyboard timing, etc.)
|
|
// before generating DH keys.
|
|
|
|
#ifndef SECURITY_H
|
|
#define SECURITY_H
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
|
|
// Key sizes (bytes)
|
|
#define SEC_DH_KEY_SIZE 128 // 1024-bit DH public key
|
|
#define SEC_XTEA_KEY_SIZE 16 // 128-bit XTEA key
|
|
|
|
// Error codes
|
|
#define SEC_SUCCESS 0
|
|
#define SEC_ERR_PARAM -1
|
|
#define SEC_ERR_NOT_READY -2
|
|
#define SEC_ERR_ALLOC -3
|
|
|
|
// Opaque types
|
|
typedef struct SecDhS SecDhT;
|
|
typedef struct SecCipherS SecCipherT;
|
|
|
|
|
|
// RNG — seed before generating keys. Hardware entropy is weak (~20 bits);
|
|
// callers should supplement with keyboard timing, mouse jitter, etc.
|
|
int secRngGatherEntropy(uint8_t *buf, int len);
|
|
void secRngAddEntropy(const uint8_t *data, int len);
|
|
void secRngBytes(uint8_t *buf, int len);
|
|
void secRngSeed(const uint8_t *entropy, int len);
|
|
|
|
// Diffie-Hellman key exchange (1024-bit, RFC 2409 Group 2)
|
|
SecDhT *secDhCreate(void);
|
|
int secDhComputeSecret(SecDhT *dh, const uint8_t *remotePub, int len);
|
|
int secDhDeriveKey(SecDhT *dh, uint8_t *key, int keyLen);
|
|
void secDhDestroy(SecDhT *dh);
|
|
int secDhGenerateKeys(SecDhT *dh);
|
|
int secDhGetPublicKey(SecDhT *dh, uint8_t *buf, int *len);
|
|
|
|
// XTEA cipher in CTR mode. CTR mode turns a block cipher into a stream
|
|
// cipher: encrypt an incrementing counter with the key to produce a
|
|
// keystream, then XOR with plaintext. Encrypt and decrypt are identical
|
|
// (XOR is its own inverse). The counter must never repeat with the same
|
|
// key, which is why secLink derives separate TX/RX keys.
|
|
SecCipherT *secCipherCreate(const uint8_t *key);
|
|
void secCipherCrypt(SecCipherT *c, uint8_t *data, int len);
|
|
void secCipherDestroy(SecCipherT *c);
|
|
void secCipherSetNonce(SecCipherT *c, uint32_t nonceLo, uint32_t nonceHi);
|
|
|
|
#endif
|